Go語言學(xué)習(xí)之將mp4通過rtmp推送流媒體服務(wù)的實現(xiàn)方法
前言
最近研究golang音視頻處理的時候,試著將mp4推送流媒體服務(wù)。下面分享一下代碼,大家有需要可以研究一下,按照自己的需求改改。
環(huán)境
需要安裝:github.com/yapingcat/gomedia
代碼
代碼如下:
package main import ( "fmt" "github.com/yapingcat/gomedia/go-codec" "github.com/yapingcat/gomedia/go-mp4" "github.com/yapingcat/gomedia/go-rtmp" "io" "net" "os" "time" ) func main() { var ( mp4Path = "./data/movie1.mp4" rtmpUrl = "rtmp://192.168.5.97:1935/live/home" ) c, err := net.Dial("tcp4", "192.168.5.97:1935") if err != nil { fmt.Println(err) } cli := rtmp.NewRtmpClient(rtmp.WithComplexHandshake(), rtmp.WithComplexHandshakeSchema(rtmp.HANDSHAKE_COMPLEX_SCHEMA1), rtmp.WithEnablePublish()) cli.OnError(func(code, describe string) { fmt.Printf("rtmp code:%s ,describe:%s\n", code, describe) }) isReady := make(chan struct{}) cli.OnStatus(func(code, level, describe string) { fmt.Printf("rtmp onstatus code:%s ,level %s ,describe:%s\n", code, describe) }) cli.OnStateChange(func(newState rtmp.RtmpState) { if newState == rtmp.STATE_RTMP_PUBLISH_START { fmt.Println("ready for publish") close(isReady) } }) cli.SetOutput(func(bytes []byte) error { _, err := c.Write(bytes) return err }) go func() { <-isReady fmt.Println("start to read file") PushRtmp(mp4Path, cli) }() cli.Start(rtmpUrl) buf := make([]byte, 4096) n := 0 for err == nil { n, err = c.Read(buf) if err != nil { continue } cli.Input(buf[:n]) } fmt.Println(err) } func PushRtmp(fileName string, cli *rtmp.RtmpClient) { mp4File, err := os.Open(fileName) if err != nil { fmt.Println(err) return } defer mp4File.Close() demuxer := mp4.CreateMp4Demuxer(mp4File) if infos, err := demuxer.ReadHead(); err != nil && err != io.EOF { fmt.Println(err) } else { fmt.Printf("%+v\n", infos) } mp4info := demuxer.GetMp4Info() fmt.Printf("%+v\n", mp4info) for { pkg, err := demuxer.ReadPacket() if err != nil { fmt.Println(err) break } if pkg.Cid == mp4.MP4_CODEC_H264 { time.Sleep(30 * time.Millisecond) cli.WriteVideo(codec.CODECID_VIDEO_H264, pkg.Data, uint32(pkg.Pts), uint32(pkg.Dts)) } else if pkg.Cid == mp4.MP4_CODEC_AAC { cli.WriteAudio(codec.CODECID_AUDIO_AAC, pkg.Data, uint32(pkg.Pts), uint32(pkg.Dts)) } else if pkg.Cid == mp4.MP4_CODEC_MP3 { cli.WriteAudio(codec.CODECID_AUDIO_MP3, pkg.Data, uint32(pkg.Pts), uint32(pkg.Dts)) } } }
代碼說明:
1、如果是其他格式的話,可以按照庫里其他格式構(gòu)建。
2、為什么在視頻幀推送要睡30ms,可以按照幀率調(diào)整,因為讀取的速度比較快,會推太快。
執(zhí)行結(jié)果:
rtmp onstatus code:NetStream.Publish.Start ,level Started publishing stream. ,describe:%!s(MISSING)
ready for publish
start to read file
[{Duration:299925 TrackId:1 Cid:1 Height:1080 Width:1920 SampleRate:0 SampleSize:0 ChannelCount:0 Timescale:24000 StartDts:0 EndDts:299882} {Duration:299990 TrackId:2 Cid:102 Height:0 Width:0 SampleRate:48000 SampleSize:16 ChannelCount:2 Timescale:48000 StartDts:0 EndDts:299968}]
{MajorBrand:1836020585 MinorVersion:512 CompatibleBrands:[1836020585 846164841 828601953 825520237] Duration:299990 Timescale:1000 CreateTime:0 ModifyTime:0}
拉流畫面:
這個代碼主要只是簡單的推流,沒有太多對視頻幀的處理。
如果有需要的話,可以自己集成一些其他的圖像處理的庫。
可以實現(xiàn)實時的視頻處理并推送的功能。
總結(jié)
到此這篇關(guān)于Go語言學(xué)習(xí)之將mp4通過rtmp推送流媒體服務(wù)實現(xiàn)的文章就介紹到這了,更多相關(guān)Go將mp4通過rtmp推送流媒體服務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
詳解Go語言strconv與其他基本數(shù)據(jù)類型轉(zhuǎn)換函數(shù)的使用
這篇文章將以 string 類型為中心,通過 strconv 標(biāo)準(zhǔn)庫,介紹其與其他基本數(shù)據(jù)類型相互轉(zhuǎn)換的函數(shù)。文中的示例代碼講解詳細(xì),感興趣的可以了解一下2022-12-12golang 定時任務(wù)方面time.Sleep和time.Tick的優(yōu)劣對比分析
這篇文章主要介紹了golang 定時任務(wù)方面time.Sleep和time.Tick的優(yōu)劣對比分析,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05詳解Go語言如何實現(xiàn)類似Python中的with上下文管理器
熟悉?Python?的同學(xué)應(yīng)該知道?Python?中的上下文管理器非常好用,那么在?Go?中是否也能實現(xiàn)上下文管理器呢,下面小編就來和大家仔細(xì)講講吧2023-07-07Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解
這篇文章主要為大家介紹了Go源碼字符串規(guī)范檢查lint工具strchecker使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06