问题
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