You are not logged in.
Pages: 1
I want to make a filename array to use with ffmpeg under BASH. For example there are six video files named video_1.h264, video_2.h264, video_3.h264, video_4.h264, video_5.h264 and video_6.h264.
I want to then concat them using ffmpeg
ffmpeg -i "concat:video_1.h264|video_2.h264|video_3.h264|video_4.h264|video_5.h264|video_6.h264" -c copy final.h264
Now I use the current code to do it with 1.h264, 2.h264, 3.h264, etc.
eval segments=\({1..$segments_variable}.h264\)
ifs=$IFS
IFS="|"
ffmpeg -i "concat:${segments[*]}" -c copy video.h264
$segments_variable is the amount of h264 files in the directory.
Now I want the code to automatically detect how many .h264 files in the directory and instead of just being number they have a title in them eg (video_1.h264)
I know how to create an array. For example
arr=( $(ls $project_*.h264) )
segments_variable=$(echo ${#arr[@]})
$project would equal in this case "video" and segments_variable finds how many files are called video_*.h264.
Any ideas
Offline
What are you trying to do: use bash arrays or do some ffmpeg magic?
'find' can supply the filenames too.
Offline
Well I know how to do the ffmpeg magic. I just want to figure out to get "video_1.h264|video_2.h264|video_3.h264" in the ffmpeg statement.
ala
ffmpeg -i "concat:video_1.h264|video_2.h264, etc, etc" -c copy final.h264
Offline
Have you tried it like this: http://trac.ffmpeg.org/wiki/How%20to%20 … ia%20files
Offline
The old style way actually doesn't work properly due to it being only stream level which is why I use the method I spoke of above. Concat Protocol the one I use works at a file level.
Offline
I'm sorry, I'm confused.
Have you read that script?
first=${@:1:1}
last=${@:$#:1}
len=$(($#-2))
inputs=${@:2:$len}
You can do e.g.
<scriptname> *.h264
Offline
That doesn't really help me. But thank you so much for your help.
I need a way to make the filelist array look like this "video_1.h264|video_2.h264" so I can put it into the ffmpeg command.
Last edited by z1lt0id (2014-02-04 05:25:52)
Offline
Let the obfuscated code contest begin:
$ cat t1
#!/bin/bash
foo=$(find -name '*.h264' -printf "|%f")
bar=$(echo $foo | sed 's/|/:/')
ffmpeg -i "concat$bar" -c copy output.h264
$ ls
bar.h264 baz.h264 foo.h264 t1
What happens if you run t1 now?
Last edited by karol (2014-02-04 05:28:07)
Offline
Karol thanks so much, i'm pretty newbie at at all of this.
The code you gave me sort of works.
But it concatted all out of order.
Input #0, h264, from 'concat:kitchen_9.h264|kitchen_4.h264|kitchen_2.h264|kitchen_6.h264|kitchen_7.h264|kitchen_12.h264|kitchen_1.h264|kitchen_10.h264|kitchen_8.h264|kitchen_5.h264|kitchen_11.h264|kitchen_3.h264'
But I would want to add say
project="kitchen"
foo=$(find -name '$project_*.h264' -printf "|%f")
bar=$(echo $foo | sed 's/|/:/')
ffmpeg -i "concat$bar" -c copy output.h264
Project being a variable that the user change via a dialog gui. But for test purposes I just made it say "kitchen". When I do this it just responds with
concat: No such file or directory
Offline
I'm not sure I get how did you introduce the kitchen thing
#!/bin/bash
project=kitchen
foo=( $(find -name "$project_*.h264" -printf "%f\n" | sort) )
bar=$(echo "${foo[@]}"| tr ' ' '|')
ffmpeg -i "concat:$bar" -c copy output.h264
This will break if you have spaces in the filenames.
Last edited by karol (2014-02-04 06:06:26)
Offline
Haven't we been down this path before?
What is wrong with lolilolicon's script in that thread?
Offline
Indeed. I tried modifying the code but alas it didn't work. Maybe I might look at it again
Offline
I think this will do what you want. The files will be sorted lexically according to your locale (I believe). If you don't want the file sorted in that order, I think you have to explicitly sort them as you wish.
#!/bin/bash
project="$1"
printf -v files "%s|" $project_*.h264
[[ $files =~ [*] ]] || ffmpeg -i "concat:${files%|}" -c copy output.h264
Offline
I think this will do what you want. The files will be sorted lexically according to your locale (I believe). If you don't want the file sorted in that order, I think you have to explicitly sort them as you wish.
#!/bin/bash project="$1" printf -v files "%s|" $project_*.h264 [[ $files =~ [*] ]] || ffmpeg -i "concat:${files%|}" -c copy output.h264
You don't really mean to check for "*" in the variable, but to avoid the case where the path expansion fails. Your check breaks when there is any "*" in the actual filenames. I suggest the `failglob` shopt for your purpose here.
I would also substitute `$project_*.h264` with `"$@"` to let the user pass the filenames, a trivial effort in exchange for much flexibility.
This silver ladybug at line 28...
Offline
Pages: 1