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

时间:2013-10-29 12:27:42

标签: ffmpeg streaming

我正在尝试将实时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文件。

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

任何人都可以帮助我吗?

提前致谢...

4 个答案:

答案 0 :(得分:66)

这是使用任何输入文件或流的HLS流的简短指南:

我遵循user1390208的方法,所以我只使用FFMPEG来生成rtmp流,然后我的服务器接收它以提供HLS。而不是Unreal / Wowza / Adob​​e,我使用免费服务器nginx和rtmp模块,这很容易设置。这就是我简单的做法: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的this设置指南。
  • This是我的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流。

一切都清楚了吗?快乐的流媒体!

答案 1 :(得分:21)

尝试将此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 Feed中可能会有一些延迟。但是,它会起作用。

答案 2 :(得分:2)

作为这个问题的更新,我设法完成了从RTMP到HLS的实时转码,而不使用ffmpeg,怎么样?

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

对于视频播放器,Video.Js的工作方式就像魅力

答案 3 :(得分:0)

如果您已经准备好RTMP实时流并作为HLS播放,则只需在流名称后添加.m3u8,然后将RTMP链接到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,因为我们已经通过 FFMPEG,所以我确实是这样。