xiph / opus-tools

A set of tools to encode, inspect, and decode audio in the Opus format.
https://opus-codec.org/
Other
218 stars 79 forks source link

How to organize the union of two opus-files encoded with the same options? #42

Closed zvezdochiot closed 3 years ago

zvezdochiot commented 5 years ago

How to organize the union of two opus-files encoded with the same options?

There is a need to merge several audiobook chapters into one opus-file without recoding and use tagging:

CHAPTER###=play time (hh:mm:ss.sss) CHAPTER###NAME=title "chapters"

How to use opus-tools and opus library for this? So far I have not answered this question.

mark4o commented 5 years ago

Sorry, opus-tools does not include a tool to combine multiple Opus files that are already encoded. opusenc can write a new Opus file with arbitrary tags but it only reads PCM audio.

zvezdochiot commented 5 years ago

Right. But theoretically, is it possible to take data from packages of two files and redistribute them to new packages?

mark4o commented 5 years ago

There is some dependence between packets but everything should converge within 80 ms.

If you have at least 80 ms of silence around the point where you are connecting the two streams and don't need to connect them with a precision more precise than one packet (typically 20 ms), then assuming that the channel configuration and gain match there should be no issue just copying the packets from the first stream followed by the audio packets from the second stream (skipping the second stream's header packets). A small amount of silence could be inserted between them if necessary. If there is no silence then there could be an audible glitch, as the first packets from the second stream may use values that will be interpreted as being relative to the last frames in the previous stream.

If at the time of encoding you know you are creating two files that you may want to reconnect later you can temporarily turn off prediction for the last frame of the first stream and the first frame of the second stream as described in https://tools.ietf.org/html/rfc7845.html#section-7.2 to avoid dependencies between those frames.

zvezdochiot commented 5 years ago

I can do this using cat + ffmpeg without recoding. But as a result, I get a bunch of warnings:

$ cat *.opus > book.opus
$ ffmpeg -i book.opus -c copy book.c.opus
$ opusinfo book.c.opus
...
WARNING: Sample count behind granule (3422743680<3427580580) in stream 1
...

There are a lot of them. It doesn `t suit me.

averms commented 5 years ago

Using cat(1) is not good because it duplicates headers and stuff. I would check out https://trac.ffmpeg.org/wiki/Concatenate

zvezdochiot commented 5 years ago

@a-vrma say> Using cat(1) is not good because it duplicates headers and stuff. I would check out

$ ffmpeg -f concat -safe 0 -i <(printf "file '$PWD/%s'\n" ./*.opus) -c copy output.opus
$ opusinfo output.opus
...
WARNING: Sample count ahead of granule (3409541760>3409494180) in stream 1
...
WARNING: Sample count ahead of granule (3422741760>3422694180) in stream 1
...
$ opusinfo output.opus | grep "WARNING" | wc -l
70713
zvezdochiot commented 3 years ago

⚠️ Not resolved !!!