Saturday, April 23, 2022

[SOLVED] How to expand bash array into arguments correctly

Issue

I'm working on a script on Bash.

The objective is pass 36 arguments to a ffmpeg via command.

Steps here:

  1. I verified the command. This one works fine:

    ffmpeg -i  "$f" -y -acodec aac -ab 128k  -vcodec copy  -f mp4 -movflags use_metadata_tags   -metadata MtsExifToolVersionNumber="12.30"  -metadata MtsFileName="00017.MTS"  -metadata MtsDirectory="."  -metadata MtsFileSize="59 MiB"  -metadata MtsFileModificationDate/Time="2020"  -metadata MtsFileAccessDate/Time="2021"  -metadata MtsFileInodeChangeDate/Time="2022"  -metadata MtsFilePermissions="-rwxr-xr-x"  -metadata MtsFileType="M2TS"  -metadata MtsFileTypeExtension="mts"  -metadata MtsMIMEType="video/m2ts"  -metadata MtsVideoStreamType="H.264 (AVC) Video"  -metadata MtsAudioBitrate="256 kbps"  -metadata MtsSurroundMode="Not indicated"  -metadata MtsAudioChannels="2"  -metadata MtsAudioStreamType="PGS Audio"  -metadata MtsImageWidth="1920"  -metadata MtsImageHeight="1080"  -metadata MtsDate/TimeOriginal="2020"  -metadata MtsApertureSetting="Auto"  -metadata MtsGain="0 dB"  -metadata MtsExposureProgram="Program AE"  -metadata MtsWhiteBalance="Auto"  -metadata MtsFocus="Auto (0.155)"  -metadata MtsImageStabilization="On (0x3f)"  -metadata MtsExposureTime="1/60"  -metadata MtsFNumber="3.4"  -metadata MtsMake="Sony"  -metadata MtsCameraModelName="HDR-CX405"  -metadata MtsWarning="[minor] The ExtractEmbedded option may find more tags in the video data"  -metadata MtsAudioSampleRate="48000"  -metadata MtsDuration="18.71 s"  -metadata MtsAperture="3.4"  -metadata MtsImageSize="1920x1080"  -metadata MtsMegapixels="2.1"  -metadata MtsShutterSpeed="1/60"  -metadata Offset="$Offset" -metadata creation_time="$DATE" "./$output/convert_exif_ok/$MP4_NAME"
    

Now.. I created a bash array and I tried to expand it directly on the command:

  ffmpeg -i  "$f" -y -acodec aac -ab 128k  -vcodec copy  -f mp4 -movflags use_metadata_tags  $(echo "${exif_2[@]}"  )   -metadata Offset="$Offset" -metadata creation_time="$DATE" "./$output/convert_exif_ok/$MP4_NAME"

And.. this doesn't work..

Seems like it's taking one argument so long instead of 36 different arguments..

This is the output:

    ffmpeg version 5.0.1 Copyright (c) 2000-2022 the FFmpeg developers
  built with Apple clang version 12.0.0 (clang-1200.0.32.29)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/5.0.1 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Input #0, mpegts, from '00017.MTS':
  Duration: 00:00:18.72, start: 1.020000, bitrate: 26466 kb/s
  Program 1
  Stream #0:0[0x1011]: Video: h264 (High) (HDPR / 0x52504448), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn
  Stream #0:1[0x1100]: Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, stereo, fltp, 256 kb/s
  Stream #0:2[0x1200]: Subtitle: hdmv_pgs_subtitle ([144][0][0][0] / 0x0090), 1920x1080
 -metadata MtsExifToolVersionNumber="12.30"  -metadata MtsFileName="00017.MTS"  -metadata MtsDirectory="."  -metadata MtsFileSize="59 MiB"  -metadata MtsFileModificationDate/Time="2020"  -metadata MtsFileAccessDate/Time="2021"  -metadata MtsFileInodeChangeDate/Time="2022"  -metadata MtsFilePermissions="-rwxr-xr-x"  -metadata MtsFileType="M2TS"  -metadata MtsFileTypeExtension="mts"  -metadata MtsMIMEType="video/m2ts"  -metadata MtsVideoStreamType="H.264 (AVC) Video"  -metadata MtsAudioBitrate="256 kbps"  -metadata MtsSurroundMode="Not indicated"  -metadata MtsAudioChannels="2"  -metadata MtsAudioStreamType="PGS Audio"  -metadata MtsImageWidth="1920"  -metadata MtsImageHeight="1080"  -metadata MtsDate/TimeOriginal="2020"  -metadata MtsApertureSetting="Auto"  -metadata MtsGain="0 dB"  -metadata MtsExposureProgram="Program AE"  -metadata MtsWhiteBalance="Auto"  -metadata MtsFocus="Auto (0.155)"  -metadata MtsImageStabilization="On (0x3f)"  -metadata MtsExposureTime="1/60"  -metadata MtsFNumber="3.4"  -metadata MtsMake="Sony"  -metadata MtsCameraModelName="HDR-CX405"  -metadata MtsWarning="[minor] The ExtractEmbedded option may find more tags in the video data"  -metadata MtsAudioSampleRate="48000"  -metadata MtsDuration="18.71 s"  -metadata MtsAperture="3.4"  -metadata MtsImageSize="1920x1080"  -metadata MtsMegapixels="2.1"  -metadata MtsShutterSpeed="1/60": File name too long

Well.. I'm sure I'm doing something wrong on the way of passing the content of the array to the arguments..

Any help?

Thanks


Solution

If you have

$ typeset -p exif_2 
declare -a exif_2='([0]=" -metadata MtsExifToolVersionNumber=\"12.30\"" ...

There are too many quotes when you create the array. -metadata and MtsExifToolVersionNumber="12.30" need to be separate elements within the array.

Try this (note that arbitrary whitespace, including newlines, is allowed in an array definition)

exif_2=(
    -movflags use_metadata_tags
    -metadata MtsExifToolVersionNumber="12.30"
    -metadata MtsFileName="00017.MTS"
    -metadata MtsDirectory="."
    -metadata MtsFileSize="59 MiB"
    -metadata MtsFileModificationDate/Time="2020"
    -metadata MtsFileAccessDate/Time="2021"
    -metadata MtsFileInodeChangeDate/Time="2022"
    -metadata MtsFilePermissions="-rwxr-xr-x"
    -metadata MtsFileType="M2TS"
    -metadata MtsFileTypeExtension="mts"
    -metadata MtsMIMEType="video/m2ts"
    -metadata MtsVideoStreamType="H.264 (AVC) Video"
    -metadata MtsAudioBitrate="256 kbps"
    -metadata MtsSurroundMode="Not indicated"
    -metadata MtsAudioChannels="2"
    -metadata MtsAudioStreamType="PGS Audio"
    -metadata MtsImageWidth="1920"
    -metadata MtsImageHeight="1080"
    -metadata MtsDate/TimeOriginal="2020"
    -metadata MtsApertureSetting="Auto"
    -metadata MtsGain="0 dB"
    -metadata MtsExposureProgram="Program AE"
    -metadata MtsWhiteBalance="Auto"
    -metadata MtsFocus="Auto (0.155)"
    -metadata MtsImageStabilization="On (0x3f)"
    -metadata MtsExposureTime="1/60"
    -metadata MtsFNumber="3.4"
    -metadata MtsMake="Sony"
    -metadata MtsCameraModelName="HDR-CX405"
    -metadata MtsWarning="[minor] The ExtractEmbedded option may find more tags in the video data"
    -metadata MtsAudioSampleRate="48000"
    -metadata MtsDuration="18.71 s"
    -metadata MtsAperture="3.4"
    -metadata MtsImageSize="1920x1080"
    -metadata MtsMegapixels="2.1"
    -metadata MtsShutterSpeed="1/60"
)

ffmpeg_opts=(
    -i  "$f"
    -y
    -acodec aac
    -ab 128k 
    -vcodec copy 
    -f mp4
    "${exif_2[@]}"
    -metadata Offset="$Offset"
    -metadata creation_time="$DATE"
)

ffmpeg "${ffmpeg_opts[@]}" "./$output/convert_exif_ok/$MP4_NAME"


Answered By - glenn jackman
Answer Checked By - Candace Johnson (WPSolving Volunteer)