-1

I am trying to use my ./script.sh like so:

./compile.sh -n NAME_ALBUM -f 000 000 000 000 -l 000 000 000 000
  • where -n is ALBUM_NAME and corresponds to the outputted filename being saved
  • where -f meaning First is a list of video filenames to come first in the playlist
  • where -l meaning Last is a list of video filenames to come last in the playlist

The playlist is then fed to ffmpeg ...

#!/bin/sh

# usage: ./compile.sh -n NAME_ALBUM -f 000 000 000 000 -l 000 000 000 000
# OPTION -n is for NAME, video file NAME.
# OPTION -f is for FIRST, video numbers to come FIRST in playlist.
# OPTION -l is for LAST, video numbers to come LAST in playlist.
# NOTE: mp4 videos are numbered as 001.mp4, 002.mp4, 003.mp4
# NOTE: if no videoss are mentioned in -f or -l then it will be ignored by default.
# Q1: possible to use more than (4) videos in -f or -l ?

while getopts ":n:f:l:" options; do

  case "${options}" in
    n)
      $1=${OPTARG}
      ;;
    f)
      $2=${OPTARG}
      ;;
    l)
      $3=${OPTARG}
      ;;
    h)
      echo "Help contents:
            ./compile.sh -n NAME_ALBUM -f 000 000 000 000 -l 000 000 000 000"
      ;;
    :) # not sure what this is
      echo "Error: -${OPTARG} requires an argument." #not sure what this is
      exit_abnormal
      ;;
    *) # or what this ones for
      exit_abnormal
      ;;
  esac
done
exit 0

# mp4 video file name that gets compiled
COMPILED=$1_$(date +'%Y-%m-%d_%H:%M:%S')

# video playlist fed to ffmpeg
VIDEO_LIST=list_$(date +'%Y-%m-%d_%H:%M:%S').txt


find *.mp4 | sed 's:\ :\\\ :g' | sed 's/^/file /' | sort -R  > $VIDEO_LIST; (printf 'g?%s?m0\n' $2 ; printf 'wq\n') | ed -s $VIDEO_LIST; ( printf 'g?%s?m$\n' $3 | tac; echo 'wq'; ) | ed -s $VIDEO_LIST; ffmpeg -f concat -i $VIDEO_LIST -c:v libx264 -crf 12 -preset slow -c:a copy $COMPILED.mp4

What exactly is preventing my script from working?

Q: What EXACTLY does this script do?

It creates the needed playlist for ffmpeg full of videos within that directory (best if videos are renamed like 001.mp4, 002.mp4, etc. this makes the additional "first/last" option easier to use) and the randomly shuffles all the videos within the playlist and gives it to ffmpeg to compile as one video. Additional Option: if desired to make some videos come first or/and last within the playlist simply input there numbers aka. filenames into command line when executing script.

  • 6
    $1, $2, $3, etc are positional parameters. You can't use them as regular shell variables. Thus, for example, replace $1=${OPTARG} with name=${OPTARG} and then replace COMPILED=$1_$(date +'%Y-%m-%d_%H:%M:%S') with COMPILED=${name}_$(date +'%Y-%m-%d_%H:%M:%S'). Do similar things to replace your references to $2 and $3. – John1024 May 21 at 6:09
  • What are you really trying to do? To concatenate a bunch of videos into a single file? Which errors do you get? – nxnev May 21 at 17:38
2

On top of what John1024 commented, arguments like -f file1 file2 file3 will actually be read as -f file1 : only the first value is read into the script, others are lost. Same goes on with your -l arguments.

What you can do is specify a string which is actually a list of values (notice the single quotes surrounding values) :

./compile.sh -n NAME_ALBUM -f 'file1 file2 file3' -l 'file7 file8 file9'

This way, you'll end with :

  • the value of your -f option to be "file1 file2 file3"
  • the value of your -l option to be "file7 file8 file9"

You "just" have to split them to get your file names. A construct like this should inspire you :

f='file1 file2 file3'; for fileName in $f; do echo "$fileName"; done

EDIT after question in comments :

Are the quotes required during usage? Or can they be hidden in the script? Because I already thought of that, but I think they would have to be used during command line usage of the script which is not what I wanted.

This is not completely clear to me, but I can tell that :

  • 'file1 file2 file3' (with quotes) is a single string (with spaces) and storing it in a variable or passing it as a parameter (like -f <value>) is perfectly feasible
  • file1 file2 file3 (without quotes) are 3 distinct strings (because the spaces acts as a parameter separator. You cannot pass 3 values to a single parameter in a -f <value> construct unless you use a hack like the one above (i.e. quotes)

Also, what about $2 $3 $4 $5 as -f and $6 $7 $8 $9 as -l ?

Mixing getopts construct and $n parameters will end up in an unreadable script. Moreover, this $n strategy involves having exactly 4 values for -f and also 4 values for -l.

My advice is still to feed your -f and -l options with list of files : 'file1 file2 file3' and to cut these lists within your script.

  • Are the quotes required during usage? Or can they be hidden in the script? Because I already thought of that, but I think they would have to be used during command line usage of the script which is not what I wanted. However the REAL underlying problem lies in the script itself, it does not operate, I don't know whats wrong as I am still very new to linux. Also, what about $2 $3 $4 $5 as -f and $6 $7 $8 $9 as -l ? – Anonymous May 21 at 13:42
1

you can use | as final char in a line, and that line will be continued.

e.g

foo | bar | wc

is equivalent to

foo |
bar |
wc
  • Note that ; will separate command like a newline.

I indent the final part of your script, insert new line on outer | and ;

last line looks like

find *.mp4 |
 sed 's:\ :\\\ :g' |
 sed 's/^/file /' | 
 sort -R  > $VIDEO_LIST

 (printf 'g?%s?m0\n' $2 ; printf 'wq\n') |
 ed -s $VIDEO_LIST

 ( printf 'g?%s?m$\n' $3 | tac; echo 'wq'; ) |
 ed -s $VIDEO_LIST

 ffmpeg -f concat -i $VIDEO_LIST -c:v libx264 -crf 12 -preset slow -c:a copy $COMPILED.mp4
  • where are $2 and $3 comming from ? command line ? use of set alpha bravo charly ? (Other answer address that point)

  • look like a missing '\n' in second sed.

  • be a adventurer submit your script to https://codereview.stackexchange.com/

  • Much cleaner and easier to use and manage. Thank you for the small lesson. Very much appreciated! – Anonymous May 23 at 12:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.