- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个需要将媒体流发布到 rtmp “摄取” url 的应用程序(如 YouTube Live 中使用的,或作为 Wowza 流引擎的输入等),我正在使用 ffmpeg 库(以编程方式,来自C/C++,不是命令行工具)来处理 rtmp 层。我已经准备好了一个工作版本,但是在将更高带宽的流传输到 ping 更差的服务器时遇到了一些问题。使用 ffmpeg "native"/builtin rtmp 实现和 librtmp 实现时都存在问题。
当通过良好的网络(特别是本地 Wowza 服务器)以低 ping 流式传输到本地目标服务器时,到目前为止,我的代码已经处理了我向它抛出的每个流并设法实时上传所有内容 - 这很重要,因为这专门用于直播。
但是,当流式传输到具有更差 ping 的远程服务器时(例如,a.rtmp.youtube.com 上的 youtube 摄取 url,对我来说有 50+ms 的 ping),较低带宽的流工作正常,但使用较高的带宽流网络未得到充分利用 - 例如,对于 400kB/s 的流,我只看到 ~140kB/s 的网络使用情况,有很多帧被延迟/丢弃,这取决于我用来处理网络推送的策略。
现在,我知道到目标服务器的网络连接不是问题,因为我可以在使用 ffmpeg 命令行工具到同一目标服务器或使用我的代码流式传输到本地 Wowza 时成功实时上传流然后将流转发到 youtube 摄取点的服务器。
所以网络连接不是问题,问题似乎在于我的代码。
我已经对我的代码的各个部分进行了计时,发现当问题出现时,调用 av_write_frame/av_interleaved_write_frame(我从不混合和匹配它们,我总是在任何特定构建中始终使用一个版本,只是我已经尝试过两者都看是否有任何区别)有时需要很长时间 - 我看到这些调用有时需要 500-1000 毫秒,尽管平均“坏情况”在 50-100 毫秒范围内。并非所有对他们的调用都需要这么长时间,大多数会立即返回,但是这些调用所花费的平均时间比平均帧持续时间要长,所以我不再获得实时上传。
在我看来,主要的嫌疑人可能是 rtmp 确认窗口机制,其中数据发送者在发送每 N 个字节后等待确认接收,然后再发送更多数据 - 这可以解释可用网络带宽不完全使用,因为客户端只是坐在那里等待响应(由于 ping 较低,这需要更长的时间),而不是使用可用带宽。虽然我还没有查看 ffmpeg 的 rtmp/librtmp 代码来查看它是否真的实现了这种节流,但它可能完全是另外一回事。
该应用程序的完整代码太多,无法在此处发布,但这里有一些重要的片段:
格式上下文创建:
const int nAVFormatContextCreateError = avformat_alloc_output_context2(&m_pAVFormatContext, nullptr, "flv", m_sOutputUrl.c_str());
m_pVideoAVStream = avformat_new_stream(m_pAVFormatContext, nullptr);
m_pVideoAVStream->id = m_pAVFormatContext->nb_streams - 1;
m_pAudioAVStream = avformat_new_stream(m_pAVFormatContext, nullptr);
m_pAudioAVStream->id = m_pAVFormatContext->nb_streams - 1;
m_pVideoAVStream->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
m_pVideoAVStream->codecpar->codec_id = AV_CODEC_ID_H264;
m_pVideoAVStream->codecpar->width = nWidth;
m_pVideoAVStream->codecpar->height = nHeight;
m_pVideoAVStream->codecpar->format = AV_PIX_FMT_YUV420P;
m_pVideoAVStream->codecpar->bit_rate = 10 * 1000 * 1000;
m_pVideoAVStream->time_base = AVRational { 1, 1000 };
m_pVideoAVStream->codecpar->extradata_size = int(nTotalSizeRequired);
m_pVideoAVStream->codecpar->extradata = (uint8_t*)av_malloc(m_pVideoAVStream->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
// Fill in the extradata here - I'm sure I'm doing that correctly.
m_pAudioAVStream->time_base = AVRational { 1, 1000 };
// Let's leave creation of m_pAudioCodecContext out of the scope of this question, I'm quite sure everything is done right there.
const int nAudioCodecCopyParamsError = avcodec_parameters_from_context(m_pAudioAVStream->codecpar, m_pAudioCodecContext);
const int nAVioOpenError = avio_open2(&m_pAVFormatContext->pb, m_sOutputUrl.c_str(), AVIO_FLAG_WRITE);
AVDictionary * pOptions = nullptr;
const int nWriteHeaderError = avformat_write_header(m_pAVFormatContext, &pOptions);
AVPacket pkt = { 0 };
av_init_packet(&pkt);
pkt.dts = nTimestamp;
pkt.pts = nTimestamp;
pkt.duration = nDuration; // I know what I have the wrong duration sometimes, but I don't think that's the issue.
pkt.data = pFrameData;
pkt.size = pFrameDataSize;
pkt.flags = bKeyframe ? AV_PKT_FLAG_KEY : 0;
pkt.stream_index = m_pVideoAVStream->index;
const int nWriteFrameError = av_write_frame(m_pAVFormatContext, &pkt); // This is where too much time is spent.
AVPacket pkt = { 0 };
av_init_packet(&pkt);
pkt.pts = m_nTimestampMs;
pkt.dts = m_nTimestampMs;
pkt.duration = m_nDurationMs;
pkt.stream_index = m_pAudioAVStream->index;
const int nWriteFrameError = av_write_frame(m_pAVFormatContext, &pkt);
最佳答案
我认为这并不能解释一切,但是,以防万一,对于处于类似情况的人,我发现的修复/解决方法是:
1)用rtmp协议(protocol)的librtmp实现构建ffmpeg
2) 使用 --enable-network 构建 ffmpeg,它为 librtmp 协议(protocol)添加了一些功能
3)将“rtmp_buffer_size”参数传递给avio_open2,并将其值增加到满意的值
我不能给你一个完整的逐步解释出了什么问题,但这至少解决了导致我问题的症状。
关于ffmpeg - 使用 ffmpeg rtmp : network bandwidth not fully utilized 进行流式发布,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42226828/
我需要从 RTMP 流中裁剪视频并将其发送到另一个总是变化的 RTMP 服务器。我的理解是我应该使用 nginx-proxy和 ffmpeg ,谁能帮我设置一下? 我想我需要将流发送到像 /strea
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 想改进这个问题?将问题更新为 on-topic对于堆栈溢出。 6年前关闭。 Improve this qu
如何在gstreamer中混合两个rtmp流? Src: nginx-rtmp 摄像头 - h.264/speex接收器:nginx-rtmp GStreamer 0.10 或 1.0 ------
我正在尝试组合/合并两个 rtmp 流,然后将它们发布到另一个流 例如: ffmpeg -i rtmp://ip:1935/live/micMyStream7 -i rtmp://ip:1935/li
有什么方法可以拒绝用户在其他网站上播放我的流吗?我正在运行带 rtmp 模块的 nginx,ubuntu 13。这是我的 nginx.conf rtmp { server {
已关闭。这个问题是 not about programming or software development 。目前不接受答案。 这个问题似乎不是关于 a specific programming
我正在开发一个使用 SoundManager2 的网络应用程序。在我的头撞到墙上并且没有让我的音乐流式传输之后,我终于在创建新的 SoundManager 声音时切换了一些 URL。 这是我之前使用的
谁能指导我做上面提到的? 基本上我想要的: 将单个视频文件流式传输到 RTMP 服务器(在我的情况下为 nginx)到链接的 python 脚本: rtmp:///stream/ 因此,理想情况下,视
我正在开发一个需要通过 rtmp 协议(protocol)进行实时广播流的 iphone 应用程序。我一直在努力寻找解决方案。我所知道的是我应该能够使用 rtmp-dump。但我是iphone dev
我正在尝试将传入的 rtmp 流保存在我的服务器上作为 mp4 文件。我正在使用 nginx-rtmp模块并从 flv 更改容器至mp4在 exec_record_done指示。这是使用 ffmpeg
这是我尝试运行的脚本,我相信问题出在这里: #!/bin/bash GIF=/home/stream1/85012216.gif STREAM_KEY=thisisasecret URL=rtmp:/
输出视频: https://youtu.be/VxfoBQjoY6E 解释: 我想:在 Opencv 中处理摄像头流并将其推送到 RTMP 服务器。我已经设置了 NGINX(RTMP 模块),并且已经
我正在尝试遵循本指南 - http://www.helping-squad.com/nginx-rtmp-compile-for-windows/ 为 Windows 编译 nginx rtmp,但是
我是这个论坛的新手,我的英语水平不是最好的! 我有一个网站,在那里我发布了摄像机的视频流,以显示在嵌套时间现场发生的事情!一个具有高 IT 技能的人为我构建了一个小服务器用于重新流 (Datarhei
我有一个闪存媒体服务器。我想在 Android 设备中创建一个实时视频聊天应用程序。 我目前正在使用 RTMP 方法来保护我的应用程序,但我不确定 RTMP 是否是保护我的应用程序的正确安全机制?你能
文件结束时如何保持流连接处于事件状态? 我正在使用 ffmpeg 4 我尝试了超时选项,但它不起作用,所以我的例子是: ffmpeg -i input.webm -timeout -f flv rtm
我有一台服务器,目前正在流出 RTMP 媒体,我需要以最小延迟(2-3 秒)播放它。 现在我正在使用 CRTMPServer 来使用流,但是由于没有不依赖 Flash 的 RTMP 播放器,因此该解决
我正在寻找一种解决方案,使用浏览器(Javascript)将笔记本电脑摄像头的数据发送到 rtmp 服务器(如 facebook live 或 youtube)。我做了研究,但没有运气。我得到了什么:
[已解决] -- 最终编辑中的解决方案 我正在使用 ffmpeg 录制 rtmp 直播,并希望添加一个标志,该标志将在新数据停止到达时自动停止处理。 如果我启动和停止脚本(通过按需终止进程来停止),一
我正在尝试从 ubuntu 启动实时(非点播)RTMP 流,但我仅使用 RTSP 成功通过 VLC 流式传输 vlc -vvv ./videos/test.mp4 --sout '#rtp{dst=1
我是一名优秀的程序员,十分优秀!