英文:
Is it possible to collect audio data then publish audio data every 0.5 second?
问题
可以收集音频数据并每0.5秒发布一次音频数据吗?
我正在使用Go RTMP服务器,使用https://github.com/yutopp/go-rtmp这个包,它运行良好。
在OnAudio()函数内部:这是处理音频数据的函数,它从OBS接收数据,解码音频数据,然后发布到VLC播放器。
这是OnAudio()的原始代码:
func (h *Handler) OnAudio(timestamp uint32, payload io.Reader) error {
var audio flvtag.AudioData
if err := flvtag.DecodeAudioData(payload, &audio); err != nil {
return err
}
flvBody := new(bytes.Buffer)
if _, err := io.Copy(flvBody, audio.Data); err != nil {
return err
}
audio.Data = flvBody
_ = h.pub.Publish(&flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: timestamp,
Data: &audio,
})
return nil
}
这段代码每0.02秒接收一次音频数据并发布它。我想修改代码,使其每0.5秒收集一次音频数据并发布。
尝试如下修改:
func (h *Handler) OnAudio(timestamp uint32, payload io.Reader) error {
var audio flvtag.AudioData
if err := flvtag.DecodeAudioData(payload, &audio); err != nil {
return err
}
// 如果flag为true,则控制startTimeStamp
if h.Flag == true {
h.startTimeStamp = timestamp
h.Buf.Reset()
}
h.Flag = false
buf := new(bytes.Buffer)
if _, err := io.Copy(buf, audio.Data); err != nil {
return err
}
if audio.AACPacketType == 0 {
audio.Data = buf
tag := &flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: h.startTimeStamp,
Data: &audio,
}
timestamp, (timestamp - h.startTimeStamp), buf.Len())
_ = h.pub.Publish(tag)
h.Flag = true
return nil
}
h.Buf.Write(buf.Bytes())
// 将音频数据收集到h.Buf中,然后每0.5秒发布一次
if timestamp-h.startTimeStamp >= 500 {
h.lastTimeStamp = timestamp
audio.Data = h.Buf
tag := &flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: h.startTimeStamp,
Data: &audio,
}
_ = h.pub.Publish(tag)
h.Flag = true
}
return nil
}
当我检查音频数据的大小时,没有数据丢失,但音频数据中断了。我的代码有问题吗?
英文:
Is it possible to collect audio data then publish audio data every 0.5 second?
I am using Go RTMP Server with https://github.com/yutopp/go-rtmp this package and it works well.
inside of function OnAudio(): this is function that processing of audio data, it receives data from OBS and DecodeAudioData and Publish to vlc player
this is original code of OnAudio()
func (h *Handler) OnAudio(timestamp uint32, payload io.Reader) error {
var audio flvtag.AudioData
if err := flvtag.DecodeAudioData(payload, &audio); err != nil {
return err
}
flvBody := new(bytes.Buffer)
if _, err := io.Copy(flvBody, audio.Data); err != nil {
return err
}
audio.Data = flvBody
_ = h.pub.Publish(&flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: timestamp,
Data: &audio,
})
return nil
}
this code receives audio data every 0.02 second and publish it.
I want to chage the code that colelct audio data until 0.5 second and publish audio data
so trying like this ...
func (h *Handler) OnAudio(timestamp uint32, payload io.Reader) error {
var audio flvtag.AudioData
if err := flvtag.DecodeAudioData(payload, &audio); err != nil {
return err
}
// if flag == true, startTimeStamp Control
if h.Flag == true {
h.startTimeStamp = timestamp
h.Buf.Reset()
}
h.Flag = false
buf := new(bytes.Buffer)
if _, err := io.Copy(buf, audio.Data); err != nil {
return err
}
if audio.AACPacketType == 0 {
audio.Data = buf
tag := &flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: h.startTimeStamp,
Data: &audio,
}
timestamp, (timestamp - h.startTimeStamp), buf.Len())
_ = h.pub.Publish(tag)
h.Flag = true
return nil
}
h.Buf.Write(buf.Bytes())
// collect audio data into h.Buf and then publish every 0.5 seconds
if timestamp-h.startTimeStamp >= 500 {
h.lastTimeStamp = timestamp
audio.Data = h.Buf
tag := &flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: h.startTimeStamp,
Data: &audio,
}
_ = h.pub.Publish(tag)
h.Flag = true
}
return nil
}
when I check the audio data size There is no Data loss but audio datas are breaking out.
Is there any problem with my code?
答案1
得分: 1
我将你的更改应用到了官方的server_relay_demo
(请参见此提交)。然后构建并运行了这个演示程序:
go build -v -o server_relay_demo .
./server_relay_demo
然后我下载了http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4,并使用ffmpeg发布它:
ffmpeg -re -stream_loop -1 -i ForBiggerBlazes.mp4 -acodec copy -vcodec copy -f flv rtmp://localhost/appname/stream
最后使用vlc播放:
$ vlc rtmp://localhost/appname/stream
VLC media player 3.0.18 Vetinari (revision 3.0.18-0-ge9eceaed4d)
[000055c1cc8f3b10] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
Qt: Session management error: Could not open network socket
[tcp @ 0x7f84280045c0] RTMP packet size mismatch 14272640 != 5642
播放失败,出现错误信息:RTMP packet size mismatch 14272640 != 5642
。
然后我将h.startTimeStamp
替换为timestamp
(请参见此提交):
tag := &flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: h.startTimeStamp,
Data: &audio,
}
这个更改使得播放正常了,但音频和视频不同步。
请尝试这个解决方案。如果仍然无法正常工作,请提供一个演示和详细的逐步指南以重现该问题。
英文:
I applied your change to the official server_relay_demo
(see this commit). Then built and run this demo:
go build -v -o server_relay_demo .
./server_relay_demo
Then I downloaded http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4, and publish it with ffmpeg:
ffmpeg -re -stream_loop -1 -i ForBiggerBlazes.mp4 -acodec copy -vcodec copy -f flv rtmp://localhost/appname/stream
And finally play it with vlc:
$ vlc rtmp://localhost/appname/stream
VLC media player 3.0.18 Vetinari (revision 3.0.18-0-ge9eceaed4d)
[000055c1cc8f3b10] main libvlc: Running vlc with the default interface. Use 'cvlc' to use vlc without interface.
Qt: Session management error: Could not open network socket
[tcp @ 0x7f84280045c0] RTMP packet size mismatch 14272640 != 5642
It failed to play with this error: RTMP packet size mismatch 14272640 != 5642
.
Then I replaced h.startTimeStamp
with timestamp
(see this commit):
tag := &flvtag.FlvTag{
TagType: flvtag.TagTypeAudio,
Timestamp: h.startTimeStamp,
Data: &audio,
}
It works with this change. Though the audio and the video are out of sync.
Please try this solution. If it still does not work, please provide a demo and a detail step by step guide to reproduce the issue.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论