Skip to main content

Notice

Please note that most of the software linked on this forum is likely to be safe to use. If you are unsure, feel free to ask in the relevant topics, or send a private message to an administrator or moderator. To help curb the problems of false positives, or in the event that you do find actual malware, you can contribute through the article linked here.
Topic: How do I encode my Opus so I would make them seekable through UPnP? (Read 1833 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

How do I encode my Opus so I would make them seekable through UPnP?

Maybe someone could have an idea here. I have the "foobar2000 mobile (UPnP client) - foobar2000 1.6.5 Windows (UPnP server)" combo, and I try to play opus with foobar2000 mobile from my server. Here's what I get:

1. Opus in OGG container (default way) - tracks are NOT seekable;
2. Opus in M4A container (I do this through ffmpeg) - tracks are seekable, but I lose gapless info and I don't know how to fix it.

Maybe there're some other choices that I miss? Thanks!
Opus VBR 256 + SoX

Re: How do I encode my Opus so I would make them seekable through UPnP?

Reply #1
1. Opus in OGG container (default way) - tracks are NOT seekable;
This is probably because ogg container requires bisect seek, which is quite inefficient or impossible on streaming.
Quote
2. Opus in M4A container (I do this through ffmpeg) - tracks are seekable, but I lose gapless info and I don't know how to fix it.
I tried a bit. ffmpeg manages to remux from normal .opus into .mp4 with the following command line keeping all the necessary bits for gapless playback.
Code: [Select]
ffmpeg -i foo.opus -c:a copy -movie_timescale 48000 foo.mp4
Note that -movie_timescale option requires relatively new ffmpeg, since it was added by this commit on 2021:
https://patchwork.ffmpeg.org/project/ffmpeg/patch/CABLWnS96xLwZ4Yx-LdjGPZUpyWfwGOqrPf+b9uNxqxK6MRfYBQ@mail.gmail.com/#64151
This is not available on default ffmpeg (4.4.2) on ubuntu 22.04, for example.

Anyway, ffmpeg can generate a .opus.mp4 file such that:
  • Have a edit list with media_time and segment_duration correctly set. (And this should be enough, according to https://opus-codec.org/docs/opus_in_isobmff.html#4.4)
  • Have a OpusHead structure in dOps box which is copied from the original. OpusHead also carries number of priming samples, which is equal to media_time in edit list above.
  • Duration of the last sample (which is declared in stts box) takes end padding into account. It's shorter than full opus frame (960 samples).

Unfortunately, having all these bits, ffmpeg itself still cannot decode this mp4 into a wav file gaplessly .
However, fb2k with ffmpeg decoder wrapper can. fb2k seems like doing some magic here.

Re: How do I encode my Opus so I would make them seekable through UPnP?

Reply #2
-movie_timescale 48000
Wow, this worked wonders, thank you so much for very useful info! So the problem wasn't the gapless info (media_time and segment_duration), it was the timescale behaviour. I used -movie_timescale 48000 and got gapless playback working in foobar2000.

This is what I use in foobar2000 encoder as parameters for ffmpeg in case someone finds it helpful:

-loglevel quiet -hide_banner -i - -c:a libopus -b:a 256K -f mp4 -movie_timescale 48000 %d
Opus VBR 256 + SoX

Re: How do I encode my Opus so I would make them seekable through UPnP?

Reply #3
Wow, this worked wonders, thank you so much for very useful info! So the problem wasn't the gapless info (media_time and segment_duration), it was the timescale behaviour. I used -movie_timescale 48000 and got gapless playback working in foobar2000.
Actually, media_time and segment_duration is dependent on timescale, as is explained here:
https://stackoverflow.com/questions/61979789/standardized-skip-intro-in-mp4-video-files
You need "-movie_timescale 48000" to make segment_duration sample accurate.