-1

I am trying to split audio files by their chapters. I have downloaded this as audio with yt-dlp with its chapters on. I have tried this very simple script to do the job:

#!/bin/sh

ffmpeg -loglevel 0 -i "$1" -f ffmetadata meta # take the metadata and output it to the file meta
cat meta | grep "END" | awk -F"=" '{print $2}' | awk -F"007000000" '{print $1}' > ends # 
cat meta | grep "title=" | awk -F"=" '{print $2}' | cut -c4- > titles
from="0"
count=1
while IFS= read -r to; do
    title=$(head -$count titles | tail -1)  
    ffmpeg -loglevel 0 -i "$1" -ss $from -to $to -c copy "$title".webm
    echo $from $to
    count=$(( $count+1 ))
    from=$to
done < ends

You see that I echo out $from and $to because I noticed they are just wrong. Why is this? When I comment out the ffmpeg command in the while loop, the variables $from and $to turn out to be correct, but when it is uncommented they just become some stupid numbers. Commented output:

0 465
465 770
770 890
890 1208
1208 1554
1554 1793
1793 2249
2249 2681
2681 2952
2952 3493
3493 3797
3797 3998
3998 4246
4246 4585
4585 5235
5235 5375
5375 5796
5796 6368
6368 6696
6696 6961

Uncommented output:

0 465
465 70
70 890
890 08
08 1554
1554 3
3 2249
2249
2952
2952 3493
3493
3998
3998 4246
4246 5235
5235 796
796 6368
6368

I tried lots of other stuff thinking that they might be the problem but they didn't change anything. One I remember is I tried havin $from and $to in the form of %H:%M:%S which, again, gave the same result. Thanks in advance.

poeplva19
  • 1
  • 3
  • 2
    Paste your script at https://shellcheck.net for validation/recommendation. Also ffmpeg most probably is [eating stdin](http://mywiki.wooledge.org/BashFAQ/089) and there might be a [buffering](http://mywiki.wooledge.org/BashFAQ/009) issue with your pipelines – Jetchisel Feb 13 '23 at 13:02
  • Is it possible, that not the variables are the issue but the output? Have you tried amending `>/dev/null` or `>/dev/null 2>&1` on your ffmpeg-command? Edit: Jetchisel is probably right, you shoud use `ffmpeg -nostdin` – blaimi Feb 13 '23 at 13:07
  • Much thanks. -nostdin in fact worked. Also thanks for the site shellcheck.net – poeplva19 Feb 13 '23 at 13:14
  • I am new to the site (and scripting actually) as you can see. What should I do with the question? – poeplva19 Feb 13 '23 at 13:15
  • You can post your own answer that worked for you and even select it as the correct answer but your question has been asked and answered quite a few times already in this forum if you just searched for ffmpeg and ssh issues with a while loop, or something like that. Also your pipelines probably can be done with one `awk` call – Jetchisel Feb 13 '23 at 13:19

1 Answers1

0

Here is an untested refactoring; hopefully it can at least help steer you in another direction.

#!/bin/sh
from=0
ffmpeg -loglevel 0 -i "$1" -f ffmetadata - |
awk -F '=' '/END/ { s=$2; sub(/007000000.*/, "", s); end[++i] = s }
    /title=/ { t=$2; sub(/^([^-]-){3}/, "", t); title[++j] = t }
    END { for(n=1; n<=i; n++) print end[n]; print title[n] }' |
while IFS="" read -r end; do
    IFS="" read -r title
    ffmpeg -loglevel 0 -i "$1" -ss "$from" -to "$end" -c copy "$title".webm </dev/null
    from="$end"
done

The Awk script reads all the data into memory, and then prints one "end" marker followed by the corresponding title on the next line; I can't be sure what your ffmpeg -f ffmetadata command outputs, so I just blindly refactored what your scripts seemed to be doing. If the output is somewhat structured you can probably read one record at a time.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Oh, I really should learn using `awk`. The problem with piping `ffmpeg -f metadata` is that it doesn't output to the command line and asks for a filename to be stated, maybe people with more `ffmpeg` knowledge knows a way to make it output to the command line. So I think I have to use a temporary file in this case, but only one rather than 3 thanks to you. – poeplva19 Feb 13 '23 at 22:33
  • Try `-` or `/dev/stdout` as the file name. – tripleee Feb 14 '23 at 05:38
  • Ugh, https://manpages.org/ffmpeg seems to be saying the metadata is in some sort of .ini format. It can probably be parsed one at a time instead of sucking it all into memory. It also seems to verify that `-` should work for writing to standard output. I have updated the answer to use that. – tripleee Feb 14 '23 at 06:21