<div dir="ltr"><p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Ralph,</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Thanks for your response</span>.</p>
<p class="MsoNormal"> </p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Unfortunately I am still in the dark. Can you kindly clarify the
following:</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"><span> </span></span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Suppose I have a 6MB opus audio file that has an audio length of 48
minutes on the server. My client application will request this opus file (via
web service) in chunks of say 512 bytes in a loop. Something like:</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">byte[] getFileChunk(int byteOffset, int length)</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">As the opus file is downloading, if the user wants to start listening to
the audio from 10th minute, he will move the audio slider accordingly. Now, the
client app will send this information to the server. Something like:</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">int getOpusAudioFileByteOffset(<wbr>long audioPositionMilliseconds)</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Now on the server (in my web service API getOpusAudioFileByteOffset),
how can I get\calculate this raw byte offset of the opus file corresponding to
this time? </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">If on the server I can calculate and provide this, the client can then again
request file download from that byte. Same as above i.e.:</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">byte[] getFileChunk(int byteOffset, int length)</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)"> </span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Thanks,</span></p>
<p class="MsoNormal"><span style="font-size:11pt;font-family:"calibri","sans-serif";color:rgb(31,73,125)">Deepak.</span></p></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Nov 15, 2016 at 12:15 AM, Ralph Giles <span dir="ltr"><<a href="mailto:giles@thaumas.net" target="_blank">giles@thaumas.net</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 2016-11-14 6:09 AM, Deepak K wrote:<br>
<br>
> I am using Http Progressive download technique to download the opus<br>
> audio in chunks. So I am not sure if the Opusfile seek API will work in<br>
> this case. Please correct me if I am wrong.<br>
<br>
</span>If you don't want to use opusfile's http client implementation<br>
(libopusurl) you can still use its seeking implementation. Just provide<br>
the `op_read_func`, `op_seek_func`, and `op_tell_func` callbacks on top<br>
of your current fetch framework. The library will call your seek<br>
implementation with the necessary byte offsets to find and resume<br>
decoding at the requested position when you call op_pcm_seek().<br>
<span class=""><br>
> Is there anyway to get or calculate the byte offset corresponding to the<br>
> PCM time position? Then I can ask the server to serve the file from that<br>
> byte onwards.<br>
<br>
</span>Yes, but the process is somewhat indirect. As Philipp said, there's no<br>
seek table in .opus resources, and they're inherently variable bitrate<br>
so you must perform a bisection search based on timestamps. Because of<br>
the minimum reasonable chuck size for http downloads, and the ability to<br>
estimate local bitrates, at most two or three seeks are necessary to<br>
find a particular pcm time position, so it doesn't perform as poorly as<br>
you might expect. On the other hand, it's not trivial to implemen. Many<br>
applications actually seek by byte offset instead, which is an<br>
acceptable user experience is some designs.<br>
<br>
If you're going to write this yourself, keep in mind the complications<br>
of decoder preroll (seek to 80 ms before the desired target and decode<br>
from there, discarding the extra output, to give the decoder a chance to<br>
settle) and chain boundaries (if you see an unrecognized Ogg stream<br>
serial number, you'll need to bisect again to find a boundary where the<br>
timestamp origin changes).<br>
<br>
Good luck, and let us know how it goes!<br>
<span class="HOEnZb"><font color="#888888"><br>
-r<br>
</font></span></blockquote></div><br></div>