node js 生成视频链接(视频流)
- video 直接视频文件
- video 直接播放视频流文件
- 本地转化一下在播放视频文件
- 本地加载获取视频流文件
- new MediaSource() 分段合成文件
参考:https://blog.csdn.net/liuyaqi1993/article/details/76560401
Readable Stream:可读流是对可消费的数据源进行的抽象,比如fs.createReadStream
Writable Stream:可写流是对流的目的地(destination)的抽象,destination运允许数据写入,比如fs.createWriteStream
Duplex Stream:双工流是同时实现了 Readable 和 Writable 接口的流,既能写又能读。比如TCP socket
Transform Stream:交换流本质上是一种Duplex流,可以将其看成输入Writable流,输出的是Readable流,也可以称之为“通过流”(through streams)。比如zlib streams。
视频流
<div class="a"><video id="video" controls preload="auto"></video></div><script>$(function() {var video = document.querySelector('#video');var mediaSource = new MediaSource();video.src = URL.createObjectURL(mediaSource);mediaSource.addEventListener('sourceopen', sourceOpen);function sourceOpen(e) {URL.revokeObjectURL(video.src);// 设置 媒体的编码类型var mime = 'video/webm; codecs="vorbis,vp8"';var mediaSource = e.target;var sourceBuffer = mediaSource.addSourceBuffer(mime);var videoUrl = 'http://localhost:9090/examples/mp4/video.webm';fetch(videoUrl).then(function(response) {console.log(response)return response.arrayBuffer();}).then(function(arrayBuffer) {sourceBuffer.addEventListener('updateend', function(e) {if (!sourceBuffer.updating && mediaSource.readyState === 'open') {mediaSource.endOfStream();// 在数据请求完成后,我们需要调用 endOfStream()。它会改变 MediaSource.readyState 为 ended 并且触发 sourceended 事件。video.play().then(function() {}).catch(function(err) {console.log(err)});}});sourceBuffer.appendBuffer(arrayBuffer);});}})
</script>
文件流
var http = require("http");
//文件处理
var fs = require("fs");
// req 路由监听空 res 上下文函数
var server = http.createServer((req, res) => {// 公共请求头res.writeHead(200, {// "Content-Type": "text/html;chaset=UTF-8","Content-Type": "image/png",//设置允许跨域的域名,*代表允许任意域名跨域"Access-Control-Allow-Origin": "*",});// 路由监控if (req.url == "/fang") {res.end("fang");} else if (req.url == "/yuan") {res.end("yuan");} else {// res.end("404");// res.end("<a href='/fang'>fang</a><br><a href='yuan'>yuan</a>");// fs.readFile(path,’binary’, function (err, file) { })的参数多了一个’binary’,以二进制流的方式读取。// res.write(file,’binary’); response也以二进制流的方式向浏览器输出。fs.readFile("./1.mp4", "binary", function (err, file) {if (err) {console.log(err);return;} else {res.write(file, "binary");res.end();}});}
});
server.listen(3000, "127.0.0.1", (res) => {console.log("http://127.0.0.1:3000/");
});
视频流
//文件处理
var fs = require("fs");
var express = require("express");
var router = express();//服务端
router.get("/video", function (req, res, next) {// let head = { "Content-Type": "video/mp4" }; video.ogvlet head = { "Content-Type": "video/*" };//需要设置HTTP HEADres.writeHead(200, head);//使用pipefs.createReadStream("./1.mp4").pipe(res);
});
router.listen(3000);
分段流
//文件处理
var fs = require("fs");
var express = require("express");
var router = express();//服务端
router.get("/video", function (req, res, next) {let path = "./1.mp4";let stat = fs.statSync(path);let fileSize = stat.size;let range = req.headers.range;// fileSize 3332038if (range) {//有range头才使用206状态码let parts = range.replace(/bytes=/, "").split("-");let start = parseInt(parts[0], 10);let end = parts[1] ? parseInt(parts[1], 10) : start + 999999;// end 在最后取值为 fileSize - 1end = end > fileSize - 1 ? fileSize - 1 : end;let chunksize = end - start + 1;let file = fs.createReadStream(path, { start, end });let head = {"Content-Range": `bytes ${start}-${end}/${fileSize}`,"Accept-Ranges": "bytes","Content-Length": chunksize,"Content-Type": "video/mp4",};res.writeHead(206, head);file.pipe(res);} else {let head = {"Content-Length": fileSize,"Content-Type": "video/mp4",};res.writeHead(200, head);fs.createReadStream(path).pipe(res);}
});router.listen(3000);
前端
参考:https://editor.csdn.net/md/?articleId=121333572
<!DOCTYPE htmlPUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head><style>body {background: black;color: #CCCCCC;}#c2 {background-image: url('foo.png');background-repeat: no-repeat;}div {float: left;border: 1px solid #444444;padding: 10px;margin: 10px;background: #3B3B3B;}</style></head><body><div><video id="video" src="http://127.0.0.1:3000/video" controls="true" /></div><div><canvas id="c1" width="160" height="96" /><canvas id="c2" width="160" height="96" /></div><script src="index.js"></script><script>processor.doLoad()</script>
</body></html>
后台
router.get('/GetStream', function(req, res, next) {let filePath = 'public/videos/frag_bunny.mp4'res.set('Content-Type', 'application/octet-stream');fs.createReadStream(filePath).pipe(res)
})
解析视频流
export default {data() {return {mediaSource: null,sourceBuffer: null,mimeType: 'video/mp4;codecs="avc1.42E01E,mp4a.40.2"'}},mounted() {// MediaSource.isTypeSupported('video/webm;codecs="vorbis,vp8"');//是否支持webm // MediaSource.isTypeSupported('video/mp4;codecs="avc1.42E01E,mp4a.40.2"')//是否支持MP4 // MediaSource.isTypeSupported('video/mp2t;codes="avc1.42E01E,mp4a.40.2"')//是否支持ts// 首先判断一下对视频格式的支持度,MediaSource提供了isTypeSupported方法if ('MediaSource' in window && MediaSource.isTypeSupported(this.mimeType)) {this.createMediaSource()} else {this.$message({message: '您的浏览器不支持MediaSource', type: 'warning'})}},methods: {createMediaSource() {// 创建MediaSource对象,并使用URL.createObjectURL来创建指向MediaSource对象的URL供video播放this.mediaSource = new MediaSource()this.$refs.h5video.src = window.URL.createObjectURL(this.mediaSource)// 监听sourceopenthis.mediaSource.addEventListener('sourceopen', this.onSourceOpen)},onSourceOpen() {let self = this// 创建一个新的 SourceBuffer 对象,然后会将它追加到 MediaSource 的 SourceBuffers 列表中。this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mimeType)// 监听buffer更新结束事件this.sourceBuffer.addEventListener('updateend', () => {// 停止streamself.mediaSource.endOfStream()// 开始播放self.$refs.h5video.play()})this.requestBuffer()},requestBuffer() {let self = this// 请求接口去拉流this.$http.get('GetStream', null, {responseType: 'arraybuffer'}).then(resp => {// 拉到的流塞进sourceBuffer里。self.sourceBuffer.appendBuffer(resp)})}}
}
php 生成网络视频
https://blog.csdn.net/weixin_34409822/article/details/91966486?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159782227719725219908200%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=159782227719725219908200&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2alltop_click~default-4-91966486.pc_ecpm_v3_pc_rank_v3&utm_term=blob&spm=1018.2118.3001.4187
node js 生成视频链接(视频流)相关推荐
- node.js 生成文件_如何使用Node.js在几秒钟内生成模拟数据
node.js 生成文件 介绍 (Introduction) In most of the applications, you need to have some static JSON data w ...
- node.js生成Excel文件 使用node-xlsx
node.js生成Excel文件 简介 尝试使用excel-export以及excel-export-next没有成功,转为使用node-xlsx成功生成Excel 从接到需求开始查询可用的库 好多博 ...
- 利用Node.js为Node.js生成HttpStatusCode辅助类并发布到npm
作为一个好的Restfull Api不仅在于service url的语义,可读性,幂等,正交,作为http状态码也很重要,一个好的Http Status Code给使用者一个很好的响应,比如200表示 ...
- node.js生成条形码图片
您可以使用第三方库,例如 node-barcode,来生成条形码图片.使用方法如下: 安装 node-barcode: npm installnode-barcode 在代码中使用: ``` var ...
- Node.js 在本地生成日志文件
文章目录 Node.js 在本地生成日志文件 1.前言 2.什么是 fs 3.new console.Console(stdout, stderr, ignoreErrors) 4.node.js 生 ...
- mysqls为node.js而编写的sql语句生成插件 crud for mysql.
mysqls It is written in JavaScript,crud for mysql.You can also use transactions very easily. mysqls ...
- 小程序使用node.js开发后台接口
目录 灵感 寻找 操作步骤 1. 准备工作 2. 使用Express生成项目 3. 创建Router级别路由 4. 创建路由处理函数模块 5. 创建连接数据库的模块 6. 启动服务器 7. 小程序里面 ...
- 提升 Node.js 应用性能的 5 个技巧
"如果nginx没有在你的节点服务器之前,那么你可能就错了."Bryan Hughes在Twitter上说 Node.js是全球领先的用JavaScript--世界上最流行的编程语 ...
- Vue.js教程视频
Vue.js教程视频链接 https://www.bilibili.com/video/av32611687/?p=1 https://www.bilibili.com/video/av3261168 ...
- Apache Ignite的Node.js客户端使用入门
为什么80%的码农都做不了架构师?>>> 介绍 Ignite原生提供了若干种主要编程语言的支持,最近,还通过瘦客户端技术对其它的编程语言提供了支持,其中在2.7版本中新增加的瘦 ...
最新文章
- mysql子查询批量找id最大的
- 2021春季学期-创新设计与实践-Lesson2
- 华为卡槽打不开怎么办_又牛又贵!华为5G折叠屏手机惊艳全球,售价1.75万!网友却讨论......
- 《2020雇佣关系趋势报告》今发布:近三成受访者兼职,近七成工作量增加、考核变严格
- .NET Core微服务之路:基于Consul最少集群实现服务的注册与发现(一)
- 游戏CFHD,狙可不是随便就起的,狙击的作用是辅助
- 审计工作存在的难点和问题_电力工程造价审计的难点与对策有哪些?学习安装电力造价广联达计价看这里!!...
- 好看的二次元个人主页导航源码 动态背景+背景音乐
- 010 、JVM实战总结: 动手实验:亲自感受一下线上系统部署时如何设置JVM内存大小
- Python + Selenium,带你分分钟搭建 Web 自动化测试框架!
- Webx3 学习笔记
- 上传图片到淘宝 API
- QEMU虚拟机源码分析概论
- android百度地图清除marker,百度地图去掉marker覆盖物的方法
- 基于JAVA自行车租借管理系统计算机毕业设计源码+系统+lw文档+部署
- 警告: A docBase D:\apache-tomcat-8.5\webapps\webapps\projectname inside the host appBase has been
- kali系统破解WiFi密码(二)
- MFC如何让背景图随窗口大小改变
- 计算机网络背诵笔记,震惊!网络搜索、数字笔记和云盘,让你变笨!!!
- 时间序列数据可视化:Pyecharts日历图
热门文章
- 赢在CSDN——谈谈程序员为什么要持续学习和创作?对CSDN的期待、个人创作的规划
- html 长度太长截断,HTML CSS 表格换行禁止 超出指定长度自动截断
- Go语言utf8汉字字符串截取处理小记
- vs未能加载项目文件。未能找到路径 c#笔记5
- 透过年报看区块链股的含金量:无一披露此业务营收 近5成停留在研究
- 2022-04-08美团笔试练题
- json模块的转义dump 和反转义 loap
- Qt_MinGW编译二维码生成库Zint及使用
- 什么是 503 服务不可用错误?
- Intellij IDEA 导入 Maven 项目详细配置以及 IDEA部署和使用过程 (Mac版)