-1

I’m writing a simple bash script named video2png, using the ffmpeg to turn certain frame of a video into png:

#!/bin/bash
ffmpeg -ss 30:00 -i "$1" -frames 1 -s 1280x880 -f image2 "$2"

I pass the video path and the wanted output path to the script as the first and the second parameter. As you can see in the script, I get these two paths through "$1" and "$2". I run the script in the Terminal on my Mac like the following:

Path1="/Users/jintai/Downloads/demon/a b/demon.mp4"
Path2="/Users/jintai/Downloads/demon/a b/demon.png"
bash video2png "$Path1" "$Path2" 

However, it seems like the flag parameter -frames for the ffmpeg in the script is misunderstood as a file under the video path since I get the following error message:

Trailing option(s) found in the command: may be ignored.
-frames: No such file or directory

How may I solve this? Thank you for your time and advice!


Editted: As suggested by @muru, I run my script with -x after bash. But the problem is still here. Here are my run and all outputs:

(base) jintai@192 missing % bash -x video2png "$Path1" "$Path2" 
+ ffmpeg -ss 30:00 -i -frames 1 -s 1280x880 -f image2
ffmpeg version 4.4.2 Copyright (c) 2000-2021 the FFmpeg developers
  built with Apple clang version 13.0.0 (clang-1300.0.29.30)
  configuration: --prefix=/opt/local --enable-swscale --enable-avfilter --enable-avresample --enable-libmp3lame --enable-libvorbis --enable-libopus --enable-librsvg --enable-libtheora --enable-libopenjpeg --enable-libmodplug --enable-libvpx --enable-libsoxr --enable-libspeex --enable-libass --enable-libbluray --enable-libzimg --enable-libzvbi --enable-lzma --enable-gnutls --enable-fontconfig --enable-libfreetype --enable-libfribidi --enable-zlib --disable-libjack --disable-libopencore-amrnb --disable-libopencore-amrwb --disable-libxcb --disable-libxcb-shm --disable-libxcb-xfixes --disable-indev=jack --enable-opencl --disable-outdev=xv --enable-audiotoolbox --enable-videotoolbox --enable-sdl2 --disable-securetransport --mandir=/opt/local/share/man --enable-shared --enable-pthreads --cc=/usr/bin/clang --enable-libdav1d --enable-libaom --enable-librav1e --enable-libsvtav1 --arch=x86_64 --enable-x86asm --enable-gpl --enable-postproc --enable-libx264 --enable-libx265 --enable-libxvid --enable-libvidstab
  libavutil      56. 70.100 / 56. 70.100
  libavcodec     58.134.100 / 58.134.100
  libavformat    58. 76.100 / 58. 76.100
  libavdevice    58. 13.100 / 58. 13.100
  libavfilter     7.110.100 /  7.110.100
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  9.100 /  5.  9.100
  libswresample   3.  9.100 /  3.  9.100
  libpostproc    55.  9.100 / 55.  9.100
Trailing option(s) found in the command: may be ignored.
-frames: No such file or directory


Edited: As suggested by @Gilles 'SO- stop being evil’, I posted my script here. Actually I’m a new learner of Bash and I used the echo to write into the script. The first code block in the first post is what I use echo to write into the script. Here is the script: video2png. Thanks you all for your suggestions! I look forward to more discussion.

  • 4
    here, in this post, the ending quotes on the PathN=... lines are some fancy Unicode quotes, which the shell will not recognize as actual quotes. I'm not sure if that's a presentation issue here, but if it's like that in your actual script too, that might cause issues. There's the same issue in the text where you mention ”$1” and ”$2”, but the rest of the quotes in the code segments seem ok. – ilkkachu Feb 21 '24 at 09:52
  • 2
    This post mixes curly quotes and straight quotes. Check them in your actual code. – Kamil Maciorowski Feb 21 '24 at 09:53
  • Thank you for your comments! I have editted the post. The Quotes problem indicated by @ilkkachu is my typo. I apologize for it. But it seems like the quote is not the origin of the problem. I still wonder the solution to my problem. – Wu Eureka Feb 21 '24 at 10:02
  • 2
    @WuEureka run the script with bash -x video2png "$Path1" "$Path2" and add the output to the post, please. – muru Feb 21 '24 at 10:07
  • So your two variables are not defined. Where do you set them? You can see in the bash -x output that they have no value. – terdon Feb 21 '24 at 10:27
  • 1
    The output you posted cannot match the code you posted. Post the actual script that you ran. – Gilles 'SO- stop being evil' Feb 21 '24 at 10:56
  • 1
    @terdon, not exactly... if the vars just weren't defined, that -i "$1" part would expand to -i '', and Bash's trace output would explicitly show the empty string arg. (And this is true even in Bash 3.2 which their Mac might have.) – ilkkachu Feb 21 '24 at 12:04
  • 1
    @ilkkachu ah yes, true. Maybe the OP hasn't quoted the variables in the actual script? – terdon Feb 21 '24 at 12:20
  • Thanks for your comment! Actually I use echo to print Path1 and Path2, and they are exactly what I want. – Wu Eureka Feb 21 '24 at 12:47
  • @WuEureka, you need to change that drive share to allow access to anyone with the link, now it asks to send a request – ilkkachu Feb 21 '24 at 13:00
  • @Gilles'SO-stopbeingevil’ Can you be a litlle more detailed? I have posted my script. Thanks! – Wu Eureka Feb 21 '24 at 13:01
  • @ilkkachu I’m sorry for that. I’ve modified it and it should be OK now. – Wu Eureka Feb 21 '24 at 13:01
  • 1
    @WuEureka, what he means is that there's a difference between having e.g. ffmpeg -i "$1" in the script, vs. ffmpeg -i $1. With the quotes, it'll pass ffmpeg a single argument, no matter what, even if it's the empty string. But that's not visible in the xtrace output. Which is why it looks like your script isn't what was posted here. – ilkkachu Feb 21 '24 at 13:05
  • 1
    And, err, now that I looked at the share, the file I got has #/bin/bash -c and ffmpeg -ss 30:00 -i -frames 1 -s 1280x880 -f image2. No reference to the command line args $1 and $2 at all and having that -c in the hashbang line can't do anything useful. I'm not sure what you mean with "I used the echo to write into the script.", but the script as shown in the post above looks exactly like it should be. The one in the google share is just broken. – ilkkachu Feb 21 '24 at 13:07

1 Answers1

5
#!/bin/bash
ffmpeg -ss 30:00 -i "$1" -frames 1 -s 1280x880 -f image2 "$2"

The script as posted in the question and replicated above looks exactly as it should be. If the script is called with two args, the first argument gets expanded in place of "$1" as one string (due to the quotes), and similarly the second in place of "$2".

Running the script as video2png "$Path1" "$Path2" also looks exactly right, the quotes keep the filenames intact, regardless of the white space.

If, instead, the script had ffmpeg -ss 30:00 -i $1 -frames 1 ... and you called it with an empty arg, or no args at all, the unquoted expansion of $1 would disappear completely, being the same as running ffmpeg -ss 30:00 -i -frames 1 ....

Compare e.g. the trace outputs and behaviour of these two:

empty= bash -x -c 'ls "$empty"'
empty= bash -x -c 'ls  $empty ' 

the first should show the explicit '' as an argument to ls, and the behaviour should be completely different.


Now, for some reason, the file you had in the share was as follows:

#/bin/bash -c
ffmpeg -ss 30:00 -i  -frames 1 -s 1280x880 -f image2

This won't work. For one, the hashbang line is missing the ! (the bang). Then, the -c option is used for passing shell commands directly from the command line, e.g. bash -c "echo foo". It won't work in a hashbang line. (Then again, you called the script explicitly through Bash, with bash video2png instead of just ./video2png, so the hashbang doesn't come into it.)

Further, that script is missing the references to the command line args $1 and $2 completely.

See also e.g.:

ilkkachu
  • 138,973
  • 5
    "I used the echo to write into the script." I wonder if OP created the script by doing echo "ffmpeg ..." > video2png or something like that. It might explain why the $1 and $2 vanished – muru Feb 21 '24 at 14:23
  • @muru, yes, something like that would explain it – ilkkachu Feb 21 '24 at 14:26