<div dir="ltr">For WebM, you can use a Block elements with DiscardPadding set to skip the trailing/leading samples at the seam points. Not all video players respect the DiscardPadding element, though (they should, but not all do).</div><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 13, 2017 at 12:42 PM, Jean-Marc Valin <span dir="ltr"><<a href="mailto:jmvalin@jmvalin.ca" target="_blank">jmvalin@jmvalin.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Andreas,<br>
<br>
So if I understand your question correctly, what you want is really<br>
short "files" that are independent, but yet create a glitchless stream<br>
when concatenated, right. For Ogg, this can be implemented with<br>
libopusenc and chaining. It works pretty well (even for really tiny<br>
files). For WebM, I'm not sure how to handle the details at the<br>
container level, but for how to handle the transition details (reset and<br>
all), I suggest you have a look at the libopusenc code. In general, the<br>
idea is to disable the prediction at the point of the transition between<br>
two files and to include the transition frames in both files.<br>
<br>
Cheers,<br>
<br>
        Jean-Marc<br>
<div class="HOEnZb"><div class="h5"><br>
On 11/08/2017 03:43 AM, Andreas Stöckel wrote:<br>
> Hi!<br>
><br>
> Short version of my question: How to produce Opus frames which can be<br>
> safely concatenated and how to embed them into a WebM file?<br>
><br>
> Long version:<br>
><br>
> I'm currently implementing a web-based audio player which streams<br>
> audio as opus/WebM using the HTML5 media source extensions. Currently,<br>
> the server decodes a set of input files to a fixed RAW audio format<br>
> (stereo, 48000 kHz) and encodes the resulting continuous RAW stream as<br>
> Opus/WebM. Having a single, uninterrupted RAW stream allows for<br>
> perfect gapless playback on the client (which only sees a single live<br>
> WebM stream), e.g. there are no interruptions whatsoever when<br>
> transitioning between continuous tracks from the same music album.<br>
><br>
> An early tech-demo of the technique can be found here [1], the source<br>
> file http_audio_server/encoder.cpp implements the relevant<br>
> opus-encoding and webm-encapsulation (but see also [2] for a condensed<br>
> version).<br>
><br>
><br>
> Now, for performance reasons I'd like to split my RAW audio into<br>
> independent blocks (say, as an example, 50 frames or 1s each), encode<br>
> these as raw Opus frames and cache them on disc ahead of time. For<br>
> each block I'd like to reset the encoder to ensure independence<br>
> between the first frame of each block and the last frames in the<br>
> previous block, e.g., using<br>
><br>
> opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE)<br>
><br>
> When the client requests a certain sequence of blocks (which may<br>
> originate from various input files in (let's pretend) any order) my<br>
> goal is to (on-demand) encapsulate the pre-encoded frames as WebM and<br>
> send them to the client.<br>
><br>
> However, in early experiments [2], resetting the encoder state at the<br>
> beginning of each block and then concatenating the frames in the WebM<br>
> container leads to clearly audible gaps in the decoded WebM stream<br>
> whenever the opus encoder has been reset.<br>
><br>
> Interestingly, such artifacts are far less pronounced (if they exist<br>
> at all), if I don't explicitly reset the encoder. However, in my real<br>
> application the encoder will at least be reset implicitly (e.g. by<br>
> starting the encoding process in multiple threads for two files which<br>
> may be played consecutively).<br>
><br>
> See [2] for a MWE which expresses what I've tried to describe above.<br>
><br>
> So to rephrase my question: if it is possible at all, how can I<br>
> independently pre-encode blocks of Opus audio frames, such that I can<br>
> concatenate them during WebM muxing without audible glitches?<br>
><br>
><br>
> In advance, thank you for your help. Please let me know I anything I<br>
> wrote is unclear, or you need more information to answer my question.<br>
><br>
><br>
> Andreas<br>
><br>
><br>
> [1] <a href="https://github.com/astoeckel/http_audio_server/" rel="noreferrer" target="_blank">https://github.com/astoeckel/<wbr>http_audio_server/</a><br>
> [2] <a href="https://github.com/astoeckel/opus_gapless_webm/" rel="noreferrer" target="_blank">https://github.com/astoeckel/<wbr>opus_gapless_webm/</a><br>
> ______________________________<wbr>_________________<br>
> opus mailing list<br>
> <a href="mailto:opus@xiph.org">opus@xiph.org</a><br>
> <a href="http://lists.xiph.org/mailman/listinfo/opus" rel="noreferrer" target="_blank">http://lists.xiph.org/mailman/<wbr>listinfo/opus</a><br>
><br>
______________________________<wbr>_________________<br>
opus mailing list<br>
<a href="mailto:opus@xiph.org">opus@xiph.org</a><br>
<a href="http://lists.xiph.org/mailman/listinfo/opus" rel="noreferrer" target="_blank">http://lists.xiph.org/mailman/<wbr>listinfo/opus</a><br>
</div></div></blockquote></div><br></div>