Multiple resolutions for HLS transcoding using FFMPEG in Node Js.

huangapple go评论79阅读模式
英文:

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(&#39;test.mp4&#39;, { timeout: 432000 })
  .addOptions([
      &quot;-profile:v baseline&quot;,
      &quot;-level 3.0&quot;,
      &quot;-start_number 0&quot;,
      &quot;-hls_time 10&quot;,
      &quot;-hls_list_size 0&quot;,
      &quot;-master_pl_name master.m3u8&quot;,
      &quot;-f hls&quot;
  ])
  .output(&quot;videos/output.m3u8&quot;)

<!-- 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=&quot;mp4a.40.5&quot;
output_64k_audio.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=620000,RESOLUTION=640x360,CODECS=&quot;avc1.4d001e,mp4a.40.2&quot;
output_360.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=812000,RESOLUTION=854x480,CODECS=&quot;avc1.4d001e,mp4a.40.2&quot;
output_480.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1272000,RESOLUTION=1280x720,CODECS=&quot;avc1.4d001f,mp4a.40.2&quot;
output_720.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1627000,RESOLUTION=1920x1080,CODECS=&quot;avc1.4d0028,mp4a.40.2&quot;
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(&#39;simple-hls&#39;);
const customRenditions = (name) =&gt; {
return [
{
width: 640,
height: 360,
profile: &#39;main&#39;,
hlsTime: &#39;10&#39;,
bv: &#39;800k&#39;,
maxrate: &#39;856k&#39;,
bufsize: &#39;1200k&#39;,
ba: &#39;96k&#39;,
ts_title: `${name}_360p`,
master_title: `${name}_360p`
},
{
width: 640,
height: 480,
profile: &#39;main&#39;,
hlsTime: &#39;10&#39;,
bv: &#39;1400k&#39;,
maxrate: &#39;1498&#39;,
bufsize: &#39;2100k&#39;,
ba: &#39;128k&#39;,
ts_title: `${name}_480p`,
master_title: `${name}_480p`
},
{
width: 1280,
height: 720,
profile: &#39;main&#39;,
hlsTime: &#39;10&#39;,
bv: &#39;2800k&#39;,
maxrate: &#39;2996k&#39;,
bufsize: &#39;4200k&#39;,
ba: &#39;128k&#39;,
ts_title: `${name}_720p`,
master_title: `${name}_720p`
},
{
width: 1920,
height: 1080,
profile: &#39;main&#39;,
hlsTime: &#39;10&#39;,
bv: &#39;5000k&#39;,
maxrate: &#39;5350k&#39;,
bufsize: &#39;7500k&#39;,
ba: &#39;192k&#39;,
ts_title: `${name}_1080p`,
master_title: `${name}_1080p`
}
]
};
try {
const transcode = new Transcoder(newFileName, fileDestFolder + &#39;/&#39;, { renditions: customRenditions(fileName), showLogs: false });
transcode.transcode();
console.log(&#39;Successfully Transcoded Video&#39;);
} catch (e) {
console.log(&#39;Something went wrong : &#39; + 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(&#39;@ffmpeg-installer/ffmpeg&#39;).path;
const ls = (0, child_process_1.spawn)(ffmpegPath, commands)

When spawning the child_process, replace &#39;ffmpeg&#39; with the path of the FFmpeg installer from its npm package and it works fine.

huangapple
  • 本文由 发表于 2023年1月4日 01:47:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/74996882.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定