Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
Using read and ffmpeg in bash - what's happening here?
View unanswered posts
View posts from last 24 hours

 
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo
View previous topic :: View next topic  
Author Message
GrandeGrabois
n00b
n00b


Joined: 16 Oct 2019
Posts: 47

PostPosted: Sun Sep 19, 2021 10:43 pm    Post subject: Using read and ffmpeg in bash - what's happening here? Reply with quote

Hello!
I'm sorry if this question is not strictly gentoo related. It's just a bash script going awkwardly wrong...

Here is the scenario: I frequently have to download music in one large "album" file. Then, I use ffmpeg to split the file into different tracks (if someone can suggest a better tool to do this...).

The ffmpeg command line goes like this
Code:
$ffmpeg -i <in_file> -acodec copy -ss <start_of_track> -to <end_of_track> <outfile>


So, I'm trying to build a simple bash script to automate that. It reads another file, in which I put a table with track entries in the format "SS,TO,TRACK_NAME"

The part of the script that reads the table and calls ffmpeg is this:
Code:
i=1
while IFS=, read -r ss to name; do
  ffmpeg -loglevel fatal -y -i "$1" -acodec copy -ss $ss -to $to "$i - ${name}.${ext}"
  ((i++))
done < "$2"

(* $ext is defined before this segment of code. $1 is the in_file (the big one) and $2 is the table file)

What is happening is that read is not always reading from the beginning of each line.

To illustrate that, here one of the tables:
Code:
00:00,02:05,Zimbo Samba
02:06,04:39,Menina Flor
04:40,09:15,Garota de Ipanema
09:16,11:51,Inútil Paisagem
11:52,14:12,Barquinho Diferente
14:13,17:23,Berimbau
17:24,20:21,Consolação
20:22,22:31,Diz que fui por aí
22:32,26:38,Sou Sem Paz
26:39,28:42,Vivo Sonhando
28:43,31:28,Só Por Amor
31:29,35:19,O Norte
35:20,39:40,Garota de Ipanema
39:41,46:52,Nanã


If I put echo's just before calling ffmpeg, to know the value of the variables $ss, $to and $name, I get this output:
Code:
Copying track 1 - Zimbo Samba
ss is 00:00
to is 02:05
Copying track 2 - Menina Flor
ss is 2:06
to is 04:39
Copying track 3 - Garota de Ipanema
ss is 4:40
to is 09:15
Copying track 4 - Inútil Paisagem
ss is 9:16
to is 11:51
Copying track 5 - Barquinho Diferente
ss is :52
to is 14:12
Invalid duration specification for ss: :52
Copying track 6 - Berimbau
ss is 14:13
to is 17:23
Copying track 7 - Consolação
ss is :24
to is 20:21
Invalid duration specification for ss: :24
Copying track 8 - Diz que fui por aí
ss is 20:22
to is 22:31
Copying track 9 - Sou Sem Paz
ss is :32
to is 26:38
Invalid duration specification for ss: :32
Copying track 10 - Vivo Sonhando
ss is 26:39
to is 28:42
Copying track 11 - Só Por Amor
ss is 43
to is 31:28
Copying track 12 - O Norte
ss is 9
to is 35:19
Copying track 13 - Garota de Ipanema
ss is
to is 39:40
Invalid duration specification for ss: -to
Copying track 14 - Nanã
ss is 39:41
to is 46:52


The 1st line is read just fine. The 2nd, 3rd and 4th are read with the first char missing. The 5th line has two chars missing, so ffmpeg produces an error. Every time there is an error, line reading returns normal on the next iteration.

If I don't call ffmpeg and just do the echo's, the whole file is read just fine and all the variables are correctly assigned.

How can ffmpeg be messing with read in this context? It seems pretty weird to me...
Back to top
View user's profile Send private message
mike155
Advocate
Advocate


Joined: 17 Sep 2010
Posts: 4438
Location: Frankfurt, Germany

PostPosted: Sun Sep 19, 2021 10:58 pm    Post subject: Reply with quote

Quote:
If I don't call ffmpeg and just do the echo's, the whole file is read just fine and all the variables are correctly assigned.

I wonder if ffmpeg reads characters from stdin?

What happens if you give ffmpeg its own stdin?
Code:
ffmpeg ... </dev/null
Back to top
View user's profile Send private message
GrandeGrabois
n00b
n00b


Joined: 16 Oct 2019
Posts: 47

PostPosted: Sun Sep 19, 2021 11:13 pm    Post subject: Reply with quote

mike155 wrote:
Quote:
If I don't call ffmpeg and just do the echo's, the whole file is read just fine and all the variables are correctly assigned.

I wonder if ffmpeg reads characters from stdin?

What happens if you give ffmpeg its own stdin?
Code:
ffmpeg ... </dev/null


Well... turns out it is precisely this that is happening here. From ffmpeg man page:
Code:
-stdin
           Enable interaction on standard input. On by default unless standard input is used as an input. To explicitly disable
           interaction you need to specify "-nostdin".

           Disabling interaction on standard input is useful, for example, if ffmpeg is in the background process group. Roughly
           the same result can be achieved with "ffmpeg ... < /dev/null" but it requires a shell.


Either using -nostdin or </dev/null makes everything work just right!

This is very interesting
Back to top
View user's profile Send private message
Hu
Administrator
Administrator


Joined: 06 Mar 2007
Posts: 21724

PostPosted: Sun Sep 19, 2021 11:25 pm    Post subject: Reply with quote

done < filename opens the file and redirects stdin for the entire loop. This is convenient and useful when the loop predicate is read, since it lets you easily step through the lines. However, as you found, it also lets processes in the loop body access that same descriptor. Since they are sharing the descriptor, a read in one process affects the position in another. If ffmpeg does not read, or did read but used lseek to undo its position change, then the sharing would work. As you found, you need to prevent ffmpeg from reading stdin. For a more complex program, you might be better served arranging that the entire inner loop body has no access to your table file. That isn't needed here, so I wouldn't bother with it.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Other Things Gentoo All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum