Pion WebRTC音频流中断,而视频正常工作。

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

Pion WebRTC Audio stream cutting out while video works

问题

我正在尝试通过Pion WebRTC将一个MP4视频发送到浏览器。

使用FFmpeg,我将其分割为Opus OGG流和Annex-B H.264视频流。视频工作正常,但音频一直在中断和恢复。它正常播放几秒钟,然后停止一秒钟,然后继续播放。

这是我用于音频的FFmpeg命令:

ffmpeg -i demo.mp4 -c:a libopus -vn -page_duration 20000 demo.ogg

这是我的传输器(缩短版):

var lastGranule uint64
for {
	pageData, pageHeader, err := ogg.ParseNextPage() // 使用Pion OggReader

    // 参考自play-from-disk示例
	sampleCount := float64(pageHeader.GranulePosition - lastGranule)
	lastGranule = pageHeader.GranulePosition
	sampleDuration := time.Duration((sampleCount/48000)*1000) * time.Millisecond

	err = audioTrack.WriteSample(media.Sample{Data: pageData, Duration: sampleDuration})
	util.HandleError(err)

	time.Sleep(sampleDuration)
}

我尝试将延迟硬编码为15毫秒,这样可以解决音频中断的问题,但是它会随机播放得太快或跳过部分内容。由于在更新FFmpeg命令之前我的视频存在故障(添加关键帧和删除B帧),我认为这也是编码器的问题。

可能的原因是什么?

更新:使用Chrome中的WebRTC日志记录,我发现经常出现以下日志行:

[27216:21992:0809/141533.175:WARNING:rtcp_receiver.cc(452)] 30 RTCP blocks were skipped due to being malformed or of unrecognized/unsupported type, during the past 10 second period.

这可能是中断的原因,尽管我无法弄清楚为什么会接收到格式错误的数据。

英文:

I am trying to send an MP4 video through Pion WebRTC to the browser.

Using FFmpeg, I split it into an Opus OGG stream and an Annex-B H.264 video stream. While the video works fine, the audio keeps cutting in and out. It plays fine for a few seconds, then stops for a second, and continues.

This is the FFmpeg command I use for audio:

ffmpeg -i demo.mp4 -c:a libopus -vn -page_duration 20000 demo.ogg

And this is my transmitter (shortened):

var lastGranule uint64
for {
	pageData, pageHeader, err := ogg.ParseNextPage() // Uses Pion OggReader

    // Taken from the play-from-disk example
	sampleCount := float64(pageHeader.GranulePosition - lastGranule)
	lastGranule = pageHeader.GranulePosition
	sampleDuration := time.Duration((sampleCount/48000)*1000) * time.Millisecond

	err = audioTrack.WriteSample(media.Sample{Data: pageData, Duration: sampleDuration})
	util.HandleError(err)

	time.Sleep(sampleDuration)
}

I tried hardcoding the delay to 15ms, which fixes the issue that it's cutting out, but then it randomly plays way too fast or starts skipping. Since I had glitchy video before updating my FFmpeg command (add keyframes and remove b-frames), I assume this is also an encoder problem.

What could be the cause for this?

Update: Using WebRTC logging in Chrome, I discovered the following log lines that occurred frequently:

[27216:21992:0809/141533.175:WARNING:rtcp_receiver.cc(452)] 30 RTCP blocks were skipped due to being malformed or of unrecognized/unsupported type, during the past 10 second period.

This is probably the reason for the cutouts, although I can't figure out why it receives malformed data.

答案1

得分: 1

问题最终是由于Go本身的问题#44343导致的Sleep时间不准确。这导致样本不是以恒定的速率发送,而是以随机的速率偏离5到15毫秒,从而导致流媒体不连续。

Sean DuBois和我在Pion存储库的最新play-from-diskplay-from-disk-h264示例中通过用Ticker替换for循环和Sleep()来修复了这个问题,Ticker更准确。

英文:

The problem in the end was an inaccuracy in the Sleep time caused by issue #44343 in Go itself. It caused the samples not to be sent at a constant rate, but at a rate that randomly was between 5 and 15ms off, resulting in a choppy stream.

Sean DuBois and me fixed this in the latest play-from-disk and play-from-disk-h264 examples in the Pion repository by replacing the for-loop and Sleep() with a Ticker, which is more accurate.

huangapple
  • 本文由 发表于 2021年8月9日 18:07:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/68710266.html
匿名

发表评论

匿名网友

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

确定