Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
424 views
in Technique[技术] by (71.8m points)

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

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...