How to make range request for any portion of a media fragment?

此生再无相见时 提交于 2019-12-31 03:53:11

问题


If we wanted to make an HTTP/1.0 or HTTP/1.1 request, for example bytes 20000 to 100000 or seconds 20 through 35 seconds of a given media resource for example, .webm or .ogg audio or .mp4 video, where the response would be a discrete media fragment capable of playback without other portions of the media resource, how would we achieve this?

For example

let headers = new Headers();
let range = 1024 * 1024;
headers.append("Range", "bytes=0-" + range); 
let request = new Request(url, {headers:headers});
fetch(request)
.then(response => response.blob())
.then(data => audio.src = URL.createObjectURL(data));

loads and media plays

let headers = new Headers();
let range = 1024 * 1024;
headers.append("Range", "bytes=" + range + "-" + range * 2);
let request = new Request(url, {headers:headers});
fetch(request)
.then(response => response.blob())
.then(data => audio.src = URL.createObjectURL(data));

logs successful 200 and 206 response statuses, though does not render media playback at <audio> element.

How to create a range request for a given media, which returns only the requested range of the resource as a discrete resource capable of playback without other portions of the media, where requested media fragment can be any discrete portion of the media resource?


回答1:


You simply can't.

You absolutely need the headers of your media file (metadata) for your browser to be able to decode the data it contains.

Different media formats will have different parsing rules, with chunks of data ordered differently and getting only a portion of the raw data will break the whole structure of the data. So with some file formats, you might be able to play the beginning of an media by supplying only the beginning of the file, but all media formats don't allow it and don't even expect an start to end reading.

What can be done though is to use the timerange parameter of the MediaElement's src:

#t=[starttime][,endtime]

const url = 'https://upload.wikimedia.org/wikipedia/commons/4/4b/011229beowulf_grendel.ogg';

btn.onclick = e => {
  // fast input check for the demo
  if (max.value > aud.duration)
    max.value = aud.duration;
  if (min.value > max.value)
    min.value = max.value - 1;
  // construct our timerange parameter
  let range = '#t=' + min.value + ',' + max.value;
  // append it to our original url
  aud.src = url + range;
}
btn.onclick();
<audio id="aud" aud controls></audio><br>
<label>start: <input id="min" type="number" value="10" min="0" max="119"></label>
<label>end: <input id="max" type="number" value="20" min="1" max="120"></label>
<button id="btn">re-load</button>


来源:https://stackoverflow.com/questions/45024915/how-to-make-range-request-for-any-portion-of-a-media-fragment

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!