我正在尝试构建使用
fluent-ffmpeg
将浏览器媒体流转换为 HLS 视频流的服务器。 (MediaStream -> Socket.IO -> 服务器 -> ffmpeg -> HLS)。
服务器代码:
io.on('connection', (socket) => {
const id = v4();
const StreamFolder = path.join(__dirname,`/stream/${id}/`);
const InputPath = path.join(StreamFolder, 'stream.webm');
const filePath = path.join(StreamFolder, 'stream.m3u8');
let writeStream: null | NodeJS.WritableStream = null;
let readStream: null | NodeJS.ReadableStream = null;
let ffmpegCommand: null | FfmpegCommand = null;
CreateStreamFolder(StreamFolder);
writeStream = createWriteStream(InputPath, { flags: 'a' });
socket.on('stream-data', async (data:ArrayBuffer) => {
const bufferData = Buffer.from(data);
if(!writeStream) return;
if(!readStream)
readStream = createReadStream(InputPath, { flags: 'r' });
writeStream.write(bufferData);
if(!ffmpegCommand) {
ffmpegCommand = Ffmpeg(InputPath)
.inputFormat('webm')
.output(filePath)
.outputOptions(['-hls_time 10', '-hls_list_size 6', '-hls_flags delete_segments', '-hls_segment_filename stream%03d.ts'])
.on('start', () => {
console.log('HLS conversion started');
})
.on('error', (error: any) => {
console.error('Error during HLS conversion:', error);
});
ffmpegCommand.run();
}
});
socket.on('disconnect', () => {
if(ffmpegCommand) ffmpegCommand.kill("SIGKILL");
RemoveStreamFolder(path.join(__dirname,`/stream/${id}`));
} );
});
客户端代码:
const socket = io();
function startStream(){
navigator.mediaDevices.getDisplayMedia({video:true,audio:true}).then(stream => {
const mediaRecorder = new MediaRecorder(stream);
mediaRecorder.ondataavailable = async e => {
socket.emit('stream-data', await e.data.arrayBuffer());
}
mediaRecorder.start(10000);
}).catch(err => console.log(err));
}
套接字本身工作并将媒体流发送到服务器。
然后ffmpeg正在转换,有时崩溃(处理输入时发现无效数据)。
但是ffmpeg不创建任何
.m3u8
或.ts
文件。
流文件夹内的唯一文件是 .webm
输入文件,因此我无法看到 hls 视频。
你找到解决办法了吗?我也面临同样的问题