You are not logged in.

#1 2014-02-04 03:22:57

z1lt0id
Member
Registered: 2012-09-20
Posts: 177

Filename arrays in bash

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

#2 2014-02-04 03:29:15

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: Filename arrays in bash

What are you trying to do: use bash arrays or do some ffmpeg magic?
'find' can supply the filenames too.

Offline

#3 2014-02-04 03:46:14

z1lt0id
Member
Registered: 2012-09-20
Posts: 177

Re: Filename arrays in bash

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

#4 2014-02-04 04:10:55

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: Filename arrays in bash

Offline

#5 2014-02-04 04:22:50

z1lt0id
Member
Registered: 2012-09-20
Posts: 177

Re: Filename arrays in bash

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

#6 2014-02-04 05:01:05

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: Filename arrays in bash

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

#7 2014-02-04 05:24:49

z1lt0id
Member
Registered: 2012-09-20
Posts: 177

Re: Filename arrays in bash

That doesn't really help me.  But thank you so much for your help. smile

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

#8 2014-02-04 05:27:43

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: Filename arrays in bash

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

#9 2014-02-04 05:38:04

z1lt0id
Member
Registered: 2012-09-20
Posts: 177

Re: Filename arrays in bash

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

#10 2014-02-04 06:04:05

karol
Archivist
Registered: 2009-05-06
Posts: 25,440

Re: Filename arrays in bash

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

#11 2014-02-04 06:08:33

jasonwryan
Anarchist
From: .nz
Registered: 2009-05-09
Posts: 30,426
Website

Re: Filename arrays in bash

Haven't we been down this path before?

What is wrong with lolilolicon's script in that thread?


Arch + dwm   •   Mercurial repos  •   Surfraw

Registered Linux User #482438

Offline

#12 2014-02-04 06:15:15

z1lt0id
Member
Registered: 2012-09-20
Posts: 177

Re: Filename arrays in bash

Indeed. I tried modifying the code but alas it didn't work. Maybe I might look at it again

Offline

#13 2014-02-05 06:54:45

rockin turtle
Member
From: Montana, USA
Registered: 2009-10-22
Posts: 227

Re: Filename arrays in bash

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

#14 2014-02-05 07:41:16

lolilolicon
Member
Registered: 2009-03-05
Posts: 1,722

Re: Filename arrays in bash

rockin turtle wrote:

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

Board footer

Powered by FluxBB