直播流播放实现
技术栈:
- 后端:node + ffmpeg + WebSocket
- 前端:vue + fiv.js
实现逻辑:
- 后端启动
WebSocket
服务,根据ffmpeg
工具实现实时转流,对实时流进行格式转换输出flv
格式,前端使用flv.js
插件播放flv
格式的视频
一、后端
安装依赖包,
fluent-ffmpeg
是基于ffmpeg
工具命令的依赖npm install fluent-ffmpeg ws websocket-stream --save
安装
ffmpeg
二进制,不安装服务端会出现报错:An error occurred: Cannot find ffmpeg
npm i @ffmpeg-installer/ffmpeg
完整代码
const WebSocket = require('ws') const webSocketStream = require('websocket-stream/stream') const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path const ffmpeg = require('fluent-ffmpeg') ffmpeg.setFfmpegPath(ffmpegPath) // 建立WebSocket服务 const wss = new WebSocket.Server({ port: 8881, perMessageDeflate: false }) // 监听连接 wss.on('connection', handleConnection) // 连接时触发事件 function handleConnection(ws, req) { // 获取前端请求的流地址(前端websocket连接时后面带上流地址) const url = req.url.slice(1) // 传入连接的ws客户端 实例化一个流 const stream = webSocketStream(ws, { binary: true }) // 通过ffmpeg命令 对实时流进行格式转换 输出flv格式 const ffmpegCommand = ffmpeg(url) .addInputOption('-analyzeduration', '100000', '-max_delay', '1000000') .on('start', function () { console.log('Stream started.') }) .on('codecData', function () { console.log('Stream codecData.') }) .on('error', function (err) { console.log('An error occured: ', err.message) stream.end() }) .on('end', function () { console.log('Stream end!') stream.end() }) .outputFormat('flv').videoCodec('copy') // .outputFormat('flv').videoCodec('copy').noAudio() // 取消音频输出 stream.on('close', function () { ffmpegCommand.kill('SIGKILL') }) try { // 执行命令 传输到实例流中返回给客户端 ffmpegCommand.pipe(stream) } catch (error) { console.log(error) } }
二、前端
安装依赖包
npm install flv.js --save
完整代码
<template> <div class="video-wrap"> <div class="input-wrap"> <input v-model="url" placeholder="请输入视频地址, 支持rtsp/rtmp格式" /> <button @click="onPlay">播放</button> </div> <video muted="muted" controls width="100%" height="600" ref="video"></video> </div> </template> <script> import flvjs from 'flv.js'; export default { data() { return { flvPlayer: null, url: 'rtmp://liteavapp.qcloud.com/live/liteavdemoplayerstreamid' }; }, beforeDestroy() { this.destoryVideo(); }, methods: { // 播放 onPlay() { if (this.url && this.isPushUrl(this.url)) { console.log(1111111111); this.play() } }, // 判断地址是否正确 isPushUrl(url) { const RegExp = /^((rtmp|rtsp|http|https):\/\/)(\S+\/)+\S+$/; return RegExp.test(url); }, // 创建video createVideo() { if (flvjs.isSupported()) { const videoElement = this.$refs.video; this.flvPlayer = flvjs.createPlayer( { type: 'flv', isLive: true, hasAudio: true, url: 'ws://localhost:8881/' + this.url }, { // cors: true, // 是否跨域 // enableWorker: true, // 是否多线程工作 enableStashBuffer: false, // 是否启用缓存 // stashInitialSize: 128, // 缓存大小(kb) 默认384kb autoCleanupSourceBuffer: true, // 是否自动清理缓存 fixAudioTimestampGap: false, //false才会音视频同步 deferLoadAfterSourceOpen: false } ); this.flvPlayer.attachMediaElement(videoElement); try { this.flvPlayer.load(); this.flvPlayer.play(); } catch (error) { console.log(error); }; // 报错重连 this.flvPlayer.on(flvjs.Events.ERROR, (errType, errDetail) => { console.log('errorType:', errType); console.log('errorDetail:', errDetail); this.play() }); } }, // 销毁video destoryVideo() { if (this.flvPlayer) { this.flvPlayer.pause(); this.flvPlayer.unload(); this.flvPlayer.detachMediaElement(); this.flvPlayer.destroy(); this.flvPlayer = null; } }, // 重播/播放 play() { if (this.flvPlayer) { this.destoryVideo(); } this.createVideo(); } } }; </script> <style scoped> .video-wrap { width: 850px; margin: 0 auto; padding: 20px; border: 1px solid #ccc; } video { background-color: #000; } .input-wrap { margin-bottom: 10px; display: flex; align-items: center; } input { height: 32px; line-height: 32px; border: 1px solid #ccc; padding: 0 10px; flex: 1; } input:focus-visible { outline: none; } button { height: 32px; width: 60px; margin-left: 10px; } </style>
三、测试url
公网 rtmp 测试地址:
邓紫棋 多美丽mv (非常流畅秒开级别,强烈推荐) 地址:rtmp://liteavapp.qcloud.com/live/liteavdemoplayerstreamid (可用) 伊拉克 Al Sharqiya 电视台 (有卡顿延迟) 地址:rtmp://ns8.indexforce.com/home/mystream (可用) 韩国GOOD TV (不推荐太卡,很慢) 地址:rtmp://mobliestream.c3tv.com:554/live/goodtv.sdp (可用)
公网 m3u8 测试地址:
http格式地址计时器 m3u8 (可用) http://devimages.apple.com/iphone/samples/bipbop/gear1/prog_index.m3u8 计时器 m3u8 (可用) http://devimages.apple.com/iphone/samples/bipbop/gear3/prog_index.m3u8 计时器 m3u8 (可用) http://devimages.apple.com/iphone/samples/bipbop/bipbopall.m3u8 大海 m3u8 (可用) http://kbs-dokdo.gscdn.com/dokdo_300/definst/dokdo_300.stream/playlist.m3u8
https格式地址
钢铁之泪 m3u8 (12:14分钟) (可用) https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8 fMP4 m3u8 (10:00分钟) (可用) https://devstreaming-cdn.apple.com/videos/streaming/examples/img_bipbop_adv_example_fmp4/master.m3u8 钢铁之泪 MP4 m3u8 (12:14分钟) (可用) https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.mp4/.m3u8 实时 Akamai m3u8 (10:00分钟) (可用) https://cph-p2p-msl.akamaized.net/hls/live/2000341/test/master.m3u8 实时 Akamai m3u8 (2:00分钟) (可用) https://moctobpltc-i.akamaihd.net/hls/live/571329/eight/playlist.m3u8 大熊兔 m3u8 (10:34分钟) (可用) https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8
公网 flv 测试地址:
大熊兔flv (可用)https://sample-videos.com/video123/flv/720/big_buck_bunny_720p_1mb.flv https://sample-videos.com/video123/flv/720/big_buck_bunny_720p_2mb.flv https://sample-videos.com/video123/flv/720/big_buck_bunny_720p_5mb.flv https://sample-videos.com/video123/flv/720/big_buck_bunny_720p_10mb.flv https://sample-videos.com/video123/flv/720/big_buck_bunny_720p_20mb.flv
公网 mkv 测试地址:
已测试 (可用)https://sample-videos.com/video123/mkv/720/big_buck_bunny_720p_1mb.mkv https://sample-videos.com/video123/mkv/720/big_buck_bunny_720p_2mb.mkv https://sample-videos.com/video123/mkv/720/big_buck_bunny_720p_5mb.mkv https://sample-videos.com/video123/mkv/720/big_buck_bunny_720p_10mb.mkv
公网 3gp 测试地址:
已测试 (可用)https://sample-videos.com/video123/3gp/144/big_buck_bunny_144p_1mb.3gp https://sample-videos.com/video123/3gp/144/big_buck_bunny_144p_2mb.3gp https://sample-videos.com/video123/3gp/144/big_buck_bunny_144p_5mb.3gp https://sample-videos.com/video123/3gp/144/big_buck_bunny_144p_10mb.3gp
公网 mp4 测试地址:
已测试 (可用)http://www.w3school.com.cn/i/movie.mp4 http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4 http://vjs.zencdn.net/v/oceans.mp4 https://media.w3.org/2010/05/sintel/trailer.mp4
2023-11-24 更新(可用) 经测试上面mp4地址很卡,特此更新下面的地址
https://v-cdn.zjol.com.cn/280443.mp4 https://v-cdn.zjol.com.cn/276982.mp4 https://v-cdn.zjol.com.cn/276984.mp4 https://v-cdn.zjol.com.cn/276985.mp4 https://media.w3.org/2010/05/sintel/trailer.mp4
1 条评论
若能在案例选择上更贴近现实,说服力会进一步提升。