2

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

alvgarci
  • 35
  • 6
  • please update the question with the complete output from `typeset -p exif_2`; this will show us the contents of the array; also, enable debugging (`set -xv`), run the command, and post the complete output (this will show us how the array contents are being expanded within the command) – markp-fuso Apr 12 '22 at 21:59
  • 1
    `$(echo "${exif_2[@]}" )` should be `"${exif_2[@]}"`. After that change, any remaining errors will be due to the contents of the `exif_2` array. It might help to run your code with tracing enabled. See [How can I debug a Bash script?](https://stackoverflow.com/q/951336/4154375). Also, use [Shellcheck](https://www.shellcheck.net/) to check your shell code for common problems. – pjh Apr 12 '22 at 22:08
  • Output of the command typeset -p exif_2 declare -a exif_2='([0]=" -metadata MtsExifToolVersionNumber=\"12.30\"" [1]=" -metadata MtsFileName=\"00023.MTS\"" [2]=" -metadata MtsDirectory=\".\"" [3]=" -metadata MtsFileSize=\"250 MiB\"" [4]=" -metadata MtsFileModificationDate/Time=\"2019\"" [5]=" -metadata MtsFileAccessDate/Time=\"2021\"" [6]=" -metadata MtsFileInodeChangeDate/Time=\"2022\"" [7]=" -metadata MtsFilePermissions=\"-rwxr-xr-x\"" [8]=" -metadata MtsFileType=\"M2TS\"" [9]=" -metadata MtsFileTypeExtension=\"mts\"" [10]=" -metadata MtsMIMEType=\"video/m2ts\"" [11]=" -metadata Mts ... – alvgarci Apr 12 '22 at 22:30
  • I modified "${exif_2[@]}" and didn't work etiher. Thanks for the debugging tip. I saw that it's expanding with quotes.. and this is what is producing the error. Is threre any way of expanding without quotes? – alvgarci Apr 12 '22 at 22:38
  • This is the output of the command. As you can see.. it also adds comma for each element of the array: ffmpeg -i 00001.MTS -y -acodec aac -ab 128k -vcodec copy -f mp4 -movflags use_metadata_tags ' -metadata MtsExifToolVersionNumber="12.30"' ' -metadata MtsFileName="00001.MTS"' ' -metadata MtsDirectory="."' ' -metadata MtsFileSize="122 MiB"' ' -metadata MtsFileModificationDate/Time="2019"' ' -metadata MtsFileAccessDate/Time="2021"' ' -metadata MtsFileInodeChangeDate/Time="2022"' ' -metadata MtsFilePermissions="-rwxr-xr-x"' ' -metadata MtsFileType="M2TS"' .... – alvgarci Apr 12 '22 at 22:39
  • Tried this command for removing quotes .... but did not work either .... ffmpeg -i "$f" -y -acodec aac -ab 128k -vcodec copy -f mp4 -movflags use_metadata_tags ${exif_2[@]/\'//} -metadata Offset="$Offset" -metadata creation_time="$DATE" "./$output/convert_exif_ok/$MP4_NAME" – alvgarci Apr 12 '22 at 22:50
  • With tracing on, the additional quotes are just for your benefit: when the command is executed those quotes are not literally present. – glenn jackman Apr 12 '22 at 22:58

1 Answers1

2

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"
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Thanks. I cannot define statically exif_2 since it comes from read exif tags on files.. therefore on any execution, it changes. Anyway, I tried and i got same error. – alvgarci Apr 13 '22 at 06:08
  • if it helps...here is the code of the array I'm creating LINE=0 exif_2=( ) for i in $(echo "${exif[*]}"); do tag=$(echo "$i" | awk 'BEGIN { FS = ":" } ; {print $1}' | awk '{for (x=1;x<=NF;x++) $x=toupper(substr($x,1,1)) substr($x,2)} 1' | sed 's/ //g' | sed 's/^/Mts/' | sed 's/^/\ -metadata\ /' ) tagvalue=$(echo "$i" | awk 'BEGIN { FS = ":" } ; {print $2}' | xargs | sed 's/^/=\"/' | sed 's/$/\"/' ) exif_2+=("$tag""$tagvalue") LINE=$((LINE+1)) done – alvgarci Apr 13 '22 at 06:20
  • Don't add "-metadata" into $tag, and don't add = and quotes to $tagvalue. Then `exif_2+=( -metadata "$tag=$tagvalue" )`. Show `declare -p exif` and we can simplify that code a lot. – glenn jackman Apr 13 '22 at 14:49
  • Hi. Modifications suggested by glenn jackman went ok after some fixing on my side. Thanks a lot – alvgarci Apr 19 '22 at 13:43