我们如何使用 ffmpeg 将实时 rtmp 流转码为实时 hls 流



我正在尝试实时将实时 rtmp 流转换为 hls 流。

看完后我有一些想法

http://sonnati.wordpress.com/2011/08/30/ffmpeg-%E2%80%93-the-swiss-army-knife-of-internet-streaming-%E2%80%93-part-iv/

我能够将实时 RTMP 流转换为 HLS,但不能在运行时转换。 当我运行命令并测试任何 HSL 文件(.m3u8 和 .ts)时,我无法看到,但是当我中断命令并在那里检查时,我根据需要获取 HLS 文件。

我在谷歌上搜索解决方案,但无法得到正确的答案。

以下是使用任何输入文件或流进行 HLS 流式处理的简短指南:

我遵循user1390208的方法,所以我只使用FFMPEG来产生rtmp流,然后我的服务器接收该流以提供HLS。我使用带有rtmp模块的免费服务器nginx而不是Unreal/Wowza/Adobe,这很容易设置。简而言之,这就是我的做法:Any input file or stream -> ffmpeg -> rtmp -> nginx server -> HLS -> Client或更详细:

输入视频文件或流(http,rtmp等)-->ffmpeg 转码实时到X.264 + AAC,输出到RTMP -->nginx获取RTMP并向用户(客户端)提供HLS。因此,在客户端,您可以使用VLC或其他任何东西并连接到nginx提供的.m3u8文件。

  • 我遵循了nginx的设置指南。
  • 这是我的nginx配置文件。
  • 这就是我如何使用 ffmpeg 将我的输入文件转码为 rtmp:

    ffmpeg -re -i mydirectory/myfile.mkv -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://localhost:12345/hls/mystream;
    

    (.mkv 是 1080p 和 5.1 声音,根据您的输入,您应该使用较低的比特率!

你从哪里获得 rtmp 流?

  • 文件?然后你可以完全使用我的方法。
  • 任何具有流 Y 的服务器 X?然后,您必须将 ffmpeg 命令更改为:

    ffmpeg -re -i rtmp://theServerX/yourStreamY -c:v libx264 -b:v 5M -pix_fmt yuv420p -c:a:0 libfdk_aac -b:a:0 480k -f flv rtmp://localhost:12345/hls/mystream;
    

    或者,如果您的RTMP流已经是H.264/AAC编码的,则可以尝试使用FFMPEG中的copy选项将内容直接流式传输到nginx。

正如你在我的nginx配置文件中看到的:

  • 我的 rtmp 服务器有一个名为"hls"的"应用程序"。这是描述nginx在哪里收听ffmpeg的rtmp流的部分,这就是为什么ffmpeg流到rtmp://localhost:12345/hls/mystream;
  • 我的 http 服务器有location /hls.这意味着在VLC中,我可以连接到http://myServer:80/hls/mystream.m3u8以访问HLS流。

一切都清楚了吗?祝您直播愉快!

试试这个RTMP到HLS命令行设置:

ffmpeg -v verbose -i rtmp://<host>:<port>/<stream> -c:v libx264 -c:a aac -ac 1 -strict -2 -crf 18 -profile:v baseline -maxrate 400k -bufsize 1835k -pix_fmt yuv420p -flags -global_header -hls_time 10 -hls_list_size 6 -hls_wrap 10 -start_number 1 <pathToFolderYouWantTo>/<streamName>.m3u8

HLS 源中可能存在一些延迟。但是,它会起作用。

作为这个问题的更新,我已经设法在不使用 ffmpeg 的情况下完成了从 RTMP 到 HLS 的实时转码,如何?

好吧,只需使用 user3069376 共享的完全相同的 nginx 配置文件,并且非常小心生成 .m3uh 宣言的路径,RTMP 模块中的 hls 选项应该会处理它。

至于视频播放器,Video.js就像一个魅力。

如果您已经准备好RTMP直播流并作为 HLS 播放,那么您只需在流名称后添加.m3u8RTMP链接到 http .例如,你有这样的链接RTMP

rtmp://XY.Y.ZX.Z/hls/chid

您只需将网址设为如下:

http://XY.Y.ZX.Z/hls/chid.m3u8

它将在iOS中流畅播放。我已经尝试了以下代码,它工作正常。

func setPlayer()
{
    // RTMP URL rtmp://XY.Y.ZX.Z/hls/chid be transcripted like this http://XY.Y.ZX.Z/hls/chid.m3u8 it will play normally.
    let videoURL = URL(string: "http://XY.Y.ZX.Z/hls/chid.m3u8")
    let playerItem = AVPlayerItem(url: videoURL!)
    let adID = AVMetadataItem.identifier(forKey: "X-TITLE", keySpace: .hlsDateRange)
    let metadataCollector = AVPlayerItemMetadataCollector(identifiers: [adID!.rawValue], classifyingLabels: nil)
    //metadataCollector.setDelegate(self, queue: DispatchQueue.main)
    playerItem.add(metadataCollector)

    let player = AVPlayer(playerItem: playerItem)
    let playerLayer = AVPlayerLayer(player: player)
    playerLayer.frame = self.view.bounds
    self.view.layer.addSublayer(playerLayer)
    self.player = player
    player.play()
}

但是由于高分辨率视频流上传,它会很慢且滞后。如果您在上传视频流时将分辨率设置为低,则在低带宽网络中也将流畅运行。

请注意:它不是通过FFMPEG进行的,因为我们已经通过RTMP运行 FFMPEG 所以我这样做了。

最新更新