如何解决如何以方便的方式在html页面中加载大型视频文件
我正在使用一个网络应用程序(php,laravel),其中有大量的视频播放工作。将要显示的视频文件很大,最大可达500到700 mb。 由于某些原因,我无法将它们视为视频标签,而像我们通常这样做的那样,将整个视频文件链接赋予src属性
// this way is not available for me
<video src="http://www.example.com/media/video_file.mp3" type="video/mp4" ></video>
我需要使用mediaSource和sourcebuffer以及blob url URL.createObjectURL(mediaSourceInstance)
的方式
但是我无法让用户等到所有视频文件都加载完毕并将其blob表示提供给媒体源后才能开始播放视频,由于视频量很大,因此无论如何这都是不可接受的。
// this is the way i mean i want to use or any way similar
//but it has the disadvantage of waiting until the whole file is loaded
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
xhr.onload = function() {
var media = new MediaSource();
var sourceBuffer = mediaSource.addSourceBuffer(mimeCodec);
var buffer = xhr.response;
sourceBuffer.appendBuffer(buffer);
var url = URL.createObjectURL(media);
videoElement.src = url;
}
xhr.open('GET','http://www.example.com/media/video_file.mp3');
xhr.send();
// this code is only for clarification it may contain bugs
我的问题是:
如何在不让用户等待所有视频文件完全下载的情况下加载这些视频文件?
注意:我已经找到了答案,但仍然需要澄清,我仍然没有足够的声誉对此事发表评论,因此,如果有人可以帮助澄清,我将包括它的链接为here。
解决方法
您可以使用Node.js Stream API
。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1.0">
<meta http-equiv="X-UA-Compatible"
content="ie=edge">
<title>video player</title>
</head>
<body>
<video src="http://localhost:3000/video" controls>
</video>
</body>
</html>
const http=require('http');
const fs=require("fs");
const path=require("path");
/* http.createServer takes a handler
function and returns a server instance;*/
const server=http.createServer((req,res)=>{
// return res.end(req.url+req.method);
if(req.method==='GET' && req.url==="/"){
/*we will send a index.html page when
user visits "/" endpoint*/
/*index.html will have video component
that displays the video*/
fs.createReadStream(path.resolve(
"index.html")).pipe(res);
return;
}
//if video content is requesting
if(req.method==='GET' && req.url==="/video"){
const filepath = path.resolve("video.mp4");
const stat = fs.statSync(filepath)
const fileSize = stat.size
const range = req.headers.range
/*when we seek the video it will put
range header to the request*/
/*if range header exists send some
part of video*/
if (range) {
//range format is "bytes=start-end",const parts =
range.replace(/bytes=/,"").split("-");
const start = parseInt(parts[0],10)
/*in some cases end may not exists,if its
not exists make it end of file*/
const end =
parts[1] ?parseInt(parts[1],10) :fileSize - 1
//chunk size is what the part of video we are sending.
const chunksize = (end - start) + 1
/*we can provide offset values as options to
the fs.createReadStream to read part of content*/
const file = fs.createReadStream(filepath,{start,end})
const head = {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,'Accept-Ranges': 'bytes','Content-Length': chunksize,'Content-Type': 'video/mp4',}
/*we should set status code as 206 which is
for partial content*/
// because video is continuosly fetched part by part
res.writeHead(206,head);
file.pipe(res);
}else{
//if not send the video from start.
/* anyway html5 video player play content
when sufficient frames available*/
// It doesn't wait for the entire video to load.
const head = {
'Content-Length': fileSize,}
res.writeHead(200,head);
fs.createReadStream(path).pipe(res);
}
}
/*if anything other than handler routes then send
400 status code,is for bad request*/
else{
res.writeHead(400);
res.end("bad request");
}
})
/*check if system has environment variable
for the port,otherwise defaults to 3000*/
const PORT = process.env.PORT || 3000;
//start the server
server.listen(PORT,() => {
console.log(`server listening on port:${PORT}`);
})
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。