Convert any live stream to flv for playback.
npm install node-live-stream-h5-flv* 项目node-live-stream-jsmpeg是将任意流转换成rtsp,然后网页基于jsmpeg-player播放,发现这种视频编码格式会导致视频质量变的很差,因此研究了一下将视频转换成h264编码格式,同时基于flv进行流式播放,网页播放则基于mpegts.js进行(flv.js作者的新作品)
* 将任意的视频直播流转换成flv流, 并在浏览器中播放, 依赖于ffmpeg进行流转换.
* 项目基于node-rtsp-stream进行二次修改,使用ffmpeg可以将任意的直播类型转换成flv流,之后可以在网页上使用mpegts.js进行播放。
* 一般配合electron开发跨平台的看直播。
* node-live-stream-h5-flv
``shell`
yarn add node-live-stream-h5-flv
或者
npm install node-live-stream-h5-flv
* 此项目需要结合ffmpeg进行使用
`shell`
yarn add ffmpeg-static
或者
npm install ffmpeg-static
* 示例代码ElectronVuevite
* 如果需要使用electron+vue+vite,可以使用模板进行创建,electron-vite-vue
* electron main.js
`js
import { app, BrowserWindow, shell, ipcMain } from 'electron'
/**
* 需要加载ffmpeg-static
*/
import ffmpegPath from "ffmpeg-static";
import LiveStream from "node-live-stream-h5-flv";
/**
* electron 自带启动代码,参考默认的electron代码
* @returns {Promise
*/
async function createWindow() {
win = new BrowserWindow({
title: 'Main window',
icon: join(process.env.PUBLIC, 'favicon.ico'),
webPreferences: {
// Warning: Enable nodeIntegration and disable contextIsolation is not secure in production
// Consider using contextBridge.exposeInMainWorld
// Read more on https://www.electronjs.org/docs/latest/tutorial/context-isolation
nodeIntegration: true,
contextIsolation: false,
webSecurity: false
},
})
// ........ 省略代码,参考electron官方
}
app.on('window-all-closed', () => {
for (const liveOpender in liveOpenders) {
try {
liveOpenders[liveOpender].stream.stop()
}catch (e) {
console.log(e)
}
}
liveOpenders = {}
win = null
if (process.platform !== 'darwin') app.quit()
})
/**
* 开启live stream
* @param liveUrl {String} 直播流地址
*/
ipcMain.on('openLiveStream', (event, liveUrl) => {
const wsPort = Math.floor(Math.random()*(1 - 100) + 100) + 64000;
if (streamOpenders[liveUrl]) {
event.returnValue = {
code: 200,
msg: '开启成功',
ws: streamOpenders[liveUrl].ws,
videoSize: streamOpenders[liveUrl].videoSize
}
} else {
const stream = new LiveStream({
streamUrl: liveUrl,
wsPort: wsPort,
ffmpegPath: app.isPackaged ? ffmpegPath.replace('app.asar', 'app.asar.unpacked') : ffmpegPath,
// printFFmpegStdout: false
})
.on('getStreamInfoError' || "forwardStreamExit", () => {
console.log("打开视频流失败,请检查网络和视频流地址.")
stream.stop()
delete streamOpenders[liveUrl]
event.returnValue = {
code: 400,
msg: '开启失败'
}
})
.once('forwardStreamSuccess', (data) => {
console.log(打开视频流成功,视频信息: ${JSON.stringify(data)})ws://localhost:${wsPort}
streamOpenders[liveUrl] = {
ws: ,
stream: stream,
videoSize: data
}
event.returnValue = {
code: 200,
msg: '开启成功',
ws: streamOpenders[liveUrl].ws,
videoSize: data
}
})
}
})
/**
* 关闭live stream
* @param liveUrl {String} 直播流地址
*/
ipcMain.on('closeLiveStream', (event, liveUrl) => {
if (streamOpenders[liveUrl]) {
// 停止解析
streamOpenders[liveUrl].stream.stop()
// 删除该项
delete streamOpenders[liveUrl]
// 返回结果
event.returnValue = {
code: 200,
msg: '关闭成功'
}
} else {
event.returnValue = {
code: 400,
msg: 未找到该${liveUrl}`
}
}
})index.html
* 网页代码或者app.vue
* 在网页中播放,可以直接使用mpegts.js.
* mpegts.js
`js
`
* 示例代码NodeApp
* Node应用 wsplay.mjs
* npm install && npm run dev
`js
import LiveStream from '../../dist/node-live-stream-h5-flv.mjs';
import ffmpegPath from "ffmpeg-static";
import c from 'child_process'
import * as httpServer from 'http-server'
const wsPort = 64321;
const httpPort = 64320;
const liveUrl = process.argv.slice(2)[0]
if (!liveUrl) {
console.log(Error 请输入直播流地址. \nUsage: \nnode ${process.argv.slice(1)[0]} rtmp://ns8.indexforce.com/home/mystream)
process.exit()
}
console.log('开始测试...')
const stream = new LiveStream({
ffmpegPath: ffmpegPath,
streamUrl: liveUrl,
wsPort: wsPort,
printFFmpegStdout: false
});
console.log('启动网页服务...')
const server = httpServer.createServer()
server.listen(httpPort, '127.0.0.1')
console.log(ws地址为: ws://127.0.0.1:${wsPort}, 正在为你打开视频流,请稍等...)
stream.once('getStreamInfoError' || "forwardStreamExit", () => {
console.log('直播流打开失败, 请检查网络和视频流地址是否正确.')
process.exit()
});
stream.once('forwardStreamSuccess', (data) => {
console.log(视频流打开成功, 视频信息为: ${JSON.stringify(data)}\n浏览器中打开地址"http://127.0.0.1:${httpPort}/play", 进行观看.)start http://127.0.0.1:${httpPort}/play
console.log('启动浏览器进行播放...')
const cmd = (process.platform==='win32') ? : open http://127.0.0.1:${httpPort}/play.html
c.exec(cmd)
});
stream.once("forwardStreamExit", ()=>{
console.log("视频流转发出现问题, 尝试重新进行视频流转发.")
stream.start()
})
``