<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Greetings and hello Maxim,<div class=""><br class=""></div><div class="">Thanks for the reply and excellent question and points.</div><div class=""><br class=""></div><div class="">So.. yes, certainly enough information (worst case scenario, the entire moov atom) could be sent down to the client to figure out what best keyframes to jump to (and then range request it, etc.)</div><div class=""><br class=""></div><div class="">However:</div><div class=""><ul class="MailOutline"><li class="">That’s potentially a lot of data in the full moov atom to go down the wire, just to know where to <i class="">start</i> playing from, for a single .mp4 file. For example, for a 2-3 hour HD TV show, that can easily exceed 10MB of moov atom that needs to head to the client before it can even start playing a single first video frame. Compared to, say, HLS/DASH where playback can begin very quickly.</li><li class="">We’re relying on the server side “clipping” for our TV News Archive ( <a href="https://tv.archive.org" class="">https://tv.archive.org</a> ) to restrict the portion of the videos we permit our users to view. So we’re always only permitting streaming of relatively short clips (~15 to 120s) since we consider this as viewing <i class="">samples</i> from a larger TV news show (ie: we aren’t a VOD type Archive — we’re serving search results and trying to help researchers, etc.)</li></ul><div class=""><br class=""></div><div class="">It seems to me that either way, the value in the mp4 module is primarily in that server-side “magic” of opening and rewriting the moov atom, and then losslessly sending the A/V packets down to the client. It saves a huge amount of bandwidth for smaller clips, seeking, and even jumping mid-way into a film or TV show — for archives and playback services that have more constraints on internal storage. The Internet Archive, in general, only makes a single .mp4 web-friendly video file from uploaded materials. We don’t have the storage to make 2-5 streaming qualities for all our videos, and chunk them into small HLS/DASH pieces with an ideal adaptive/feedback constantly changing quality system (like bigger players like Netflix, YouTube, etc.)</div><div class=""><br class=""></div><div class="">I figure the “begin video immediately” patch (this patch) could be useful to others, writ-large. It certainly has been of keen interest to our TV viewers and researchers and data visualization folks.</div><div class="">I <i class="">suspect</i> that most of the users of this mp4 module might find the “being video immediately” (perceptively) a nice optional improvement.</div><div class=""><br class=""></div><div class="">I suppose a middle ground (but would also be a change/patch) could be to always start at the keyframe before the wanted start-point — and have the client, with JS, always seek to the desired start point. However, it’s definitely nice magic to request a specific start/end point, and get exactly that, down to 1/10th of a second, with no need for client JS to seek. They can play directly in all browsers and mobile as a legit .mp4 file that’s been efficiently served up just for you, on demand, losslessly. Magic! :) </div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">And as a sidenote, I must confess, that the 3500 lines of C code (in a single file!), would normally be a run-away-screaming situation for me. However, never in my life (and early start with C) have I seen such well-structured and clever C code like that. I was pretty speechless exploring it!</div><div class=""><br class=""></div><div class="">Thanks for the consideration,</div><div class="">-Tracey</div><div class=""><br class=""></div><div><br class=""><blockquote type="cite" class=""><div class="">On Jun 4, 2021, at 10:38 AM, Maxim Dounin <<a href="mailto:mdounin@mdounin.ru" class="">mdounin@mdounin.ru</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Hello!<br class=""><br class="">On Thu, Jun 03, 2021 at 07:54:49PM +0000, Tracey Jaquith wrote:<br class=""><br class=""><blockquote type="cite" class=""># HG changeset patch<br class=""># User Tracey Jaquith <<a href="mailto:tracey@archive.org" class="">tracey@archive.org</a>><br class=""># Date 1622678642 0<br class=""># Thu Jun 03 00:04:02 2021 +0000<br class=""># Node ID 5da9c62fa61016600f2c59982ae184e2811be427<br class=""># Parent 5f765427c17ac8cf753967387562201cf4f78dc4<br class="">Add optional "&exact=1" CGI arg to show video between keyframes.<br class=""><br class=""><a href="http://archive.org" class="">archive.org</a> has been using mod_h264_streaming with an "&exact=1" patch from me since 2013.<br class="">We just moved to nginx mp4 module and are using this patch.<br class="">The technique is to find the keyframe just before the desired "start" time, and send<br class="">that down the wire so video playback can start immediately.<br class="">Next calculate how many video samples are between the keyframe and desired "start" time<br class="">and update the STTS atom where those samples move the duration from (typically) 1001 to 1.<br class="">This way, initial unwanted video frames play at ~1/30,000s -- so visually the<br class="">video & audio start playing immediately.<br class=""></blockquote><br class="">So, effectively, this makes invalid streaming requests (not <br class="">starting at a keyframe) to return the same data as valid ones <br class="">(starting at a keyframe). A properly written player should be <br class="">able to achieve the same result by making correct streaming <br class="">requests.<br class=""><br class="">Any specific reasons to do this within nginx instead of fixing the <br class="">player? Or, given the fact that Flash is effectively dead, by <br class="">simply using HTML5 video with appropriate seeking?<br class=""><br class="">-- <br class="">Maxim Dounin<br class=""><a href="http://mdounin.ru/" class="">http://mdounin.ru/</a><br class="">_______________________________________________<br class="">nginx-devel mailing list<br class="">nginx-devel@nginx.org<br class="">http://mailman.nginx.org/mailman/listinfo/nginx-devel<br class=""></div></div></blockquote></div><div class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div style="color: rgb(0, 0, 0); letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">@tracey_pooh</div><div class="">TV Architect <a href="https://archive.org/tv" class="">https://archive.org/tv</a></div></div></div><br class="Apple-interchange-newline"></div><br class="Apple-interchange-newline"></div><br class="Apple-interchange-newline"></div><br class="Apple-interchange-newline"><br class="Apple-interchange-newline">
</div>
<br class=""></div></body></html>