英文:
Multiple resolutions for HLS transcoding using FFMPEG in Node Js
问题
我正在进行一个Node.js项目,用FFMPEG将上传的MP4文件转换成HLS格式(.m3u8)。我开发了一个类似这样的函数,
ffmpeg('test.mp4', { timeout: 432000 })
.addOptions([
"-profile:v baseline",
"-level 3.0",
"-start_number 0",
"-hls_time 10",
"-hls_list_size 0",
"-master_pl_name master.m3u8",
"-f hls"
])
.output("videos/output.m3u8")
问题: 这个函数如预期工作。但现在我希望视频以360、480、720和1080多种格式进行转码,并期望输出一个类似于以下的.m3u8主文件:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=72000,CODECS="mp4a.40.5"
output_64k_audio.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=620000,RESOLUTION=640x360,CODECS="avc1.4d001e,mp4a.40.2"
output_360.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=812000,RESOLUTION=854x480,CODECS="avc1.4d001e,mp4a.40.2"
output_480.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1272000,RESOLUTION=1280x720,CODECS="avc1.4d001f,mp4a.40.2"
output_720.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1627000,RESOLUTION=1920x1080,CODECS="avc1.4d0028,mp4a.40.2"
output_1080.m3u8
请帮我提供一个解决方案。
英文:
I working on a node js project to convert uploaded mp4 files to HLS format (.m3u8) using FFMPEG.
I've developed a function like this,
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
ffmpeg('test.mp4', { timeout: 432000 })
.addOptions([
"-profile:v baseline",
"-level 3.0",
"-start_number 0",
"-hls_time 10",
"-hls_list_size 0",
"-master_pl_name master.m3u8",
"-f hls"
])
.output("videos/output.m3u8")
<!-- end snippet -->
Question: This function is working as expected. But now I want the video to be transcoded in multiple formats in 360, 480, 720 and 1080 and expect an output of .m3u8 master file somewhat like
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-html -->
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=72000,CODECS="mp4a.40.5"
output_64k_audio.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=620000,RESOLUTION=640x360,CODECS="avc1.4d001e,mp4a.40.2"
output_360.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=812000,RESOLUTION=854x480,CODECS="avc1.4d001e,mp4a.40.2"
output_480.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1272000,RESOLUTION=1280x720,CODECS="avc1.4d001f,mp4a.40.2"
output_720.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1627000,RESOLUTION=1920x1080,CODECS="avc1.4d0028,mp4a.40.2"
output_1080.m3u8
<!-- end snippet -->
Please help me with a solution to this.
答案1
得分: 0
我找到了一个解决这个问题的包simple-hls,以下是最终解决方案:
const { Transcoder } = require('simple-hls');
const customRenditions = (name) => {
return [
{
width: 640,
height: 360,
profile: 'main',
hlsTime: '10',
bv: '800k',
maxrate: '856k',
bufsize: '1200k',
ba: '96k',
ts_title: `${name}_360p`,
master_title: `${name}_360p`
},
{
width: 640,
height: 480,
profile: 'main',
hlsTime: '10',
bv: '1400k',
maxrate: '1498',
bufsize: '2100k',
ba: '128k',
ts_title: `${name}_480p`,
master_title: `${name}_480p`
},
{
width: 1280,
height: 720,
profile: 'main',
hlsTime: '10',
bv: '2800k',
maxrate: '2996k',
bufsize: '4200k',
ba: '128k',
ts_title: `${name}_720p`,
master_title: `${name}_720p`
},
{
width: 1920,
height: 1080,
profile: 'main',
hlsTime: '10',
bv: '5000k',
maxrate: '5350k',
bufsize: '7500k',
ba: '192k',
ts_title: `${name}_1080p`,
master_title: `${name}_1080p`
}
]
};
try {
const transcode = new Transcoder(newFileName, fileDestFolder + '/', { renditions: customRenditions(fileName), showLogs: false });
transcode.transcode();
console.log('Successfully Transcoded Video');
} catch (e) {
console.log('Something went wrong : ' + e);
}
请注意,此包需要您在计算机上安装FFmpeg软件。在我的情况下,我找到了一种在不安装FFmpeg的情况下使用simple-hls的方法,通过使用另一个包@ffmpeg-installer/ffmpeg并编辑包的node modules文件/node_modules/simple-hls/lib/index.js
。
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ls = (0, child_process_1.spawn)(ffmpegPath, commands)
在生成child_process时,请将'ffmpeg'
替换为来自其npm包的FFmpeg安装程序的路径,它可以正常工作。
英文:
I've found a package simple-hls which solves this issue,
here is the final solution:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const { Transcoder } = require('simple-hls');
const customRenditions = (name) => {
return [
{
width: 640,
height: 360,
profile: 'main',
hlsTime: '10',
bv: '800k',
maxrate: '856k',
bufsize: '1200k',
ba: '96k',
ts_title: `${name}_360p`,
master_title: `${name}_360p`
},
{
width: 640,
height: 480,
profile: 'main',
hlsTime: '10',
bv: '1400k',
maxrate: '1498',
bufsize: '2100k',
ba: '128k',
ts_title: `${name}_480p`,
master_title: `${name}_480p`
},
{
width: 1280,
height: 720,
profile: 'main',
hlsTime: '10',
bv: '2800k',
maxrate: '2996k',
bufsize: '4200k',
ba: '128k',
ts_title: `${name}_720p`,
master_title: `${name}_720p`
},
{
width: 1920,
height: 1080,
profile: 'main',
hlsTime: '10',
bv: '5000k',
maxrate: '5350k',
bufsize: '7500k',
ba: '192k',
ts_title: `${name}_1080p`,
master_title: `${name}_1080p`
}
]
};
try {
const transcode = new Transcoder(newFileName, fileDestFolder + '/', { renditions: customRenditions(fileName), showLogs: false });
transcode.transcode();
console.log('Successfully Transcoded Video');
} catch (e) {
console.log('Something went wrong : ' + e);
}
<!-- end snippet -->
Note that this package requires you to install FFmpeg software on your machine. In my case, I've found a way to use simple-hls without installing FFmpeg by using another package @ffmpeg-installer/ffmpeg and editing the package's node modules file /node_modules/simple-hls/lib/index.js
.
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ls = (0, child_process_1.spawn)(ffmpegPath, commands)
When spawning the child_process, replace 'ffmpeg'
with the path of the FFmpeg installer from its npm package and it works fine.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论