Go語(yǔ)言學(xué)習(xí)之將mp4通過(guò)rtmp推送流媒體服務(wù)的實(shí)現(xiàn)方法
前言
最近研究golang音視頻處理的時(shí)候,試著將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))
}
}
}代碼說(shuō)明:
1、如果是其他格式的話,可以按照庫(kù)里其他格式構(gòu)建。
2、為什么在視頻幀推送要睡30ms,可以按照幀率調(diào)整,因?yàn)樽x取的速度比較快,會(huì)推太快。
執(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}
拉流畫(huà)面:

這個(gè)代碼主要只是簡(jiǎn)單的推流,沒(méi)有太多對(duì)視頻幀的處理。
如果有需要的話,可以自己集成一些其他的圖像處理的庫(kù)。
可以實(shí)現(xiàn)實(shí)時(shí)的視頻處理并推送的功能。
總結(jié)
到此這篇關(guān)于Go語(yǔ)言學(xué)習(xí)之將mp4通過(guò)rtmp推送流媒體服務(wù)實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Go將mp4通過(guò)rtmp推送流媒體服務(wù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀
這篇文章主要為大家介紹了Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
Go 并發(fā)讀寫(xiě) sync.map 詳細(xì)
閱讀本文你將會(huì)明確 sync.Map 和原生 map +互斥鎖/讀寫(xiě)鎖之間的性能情況。標(biāo)準(zhǔn)庫(kù) sync.Map 雖說(shuō)支持并發(fā)讀寫(xiě) map,但更適用于讀多寫(xiě)少的場(chǎng)景,因?yàn)樗麑?xiě)入的性能比較差,使用時(shí)要考慮清楚這一點(diǎn)。2021-10-10
golang使用mTLS實(shí)現(xiàn)雙向加密認(rèn)證http通信
這篇文章主要為大家介紹了golang如何調(diào)用mTLS實(shí)現(xiàn)雙向加密認(rèn)證http通信,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,需要的小伙伴可以參考下2023-08-08
Go語(yǔ)言擴(kuò)展原語(yǔ)之Semaphore的用法詳解
Go語(yǔ)言的擴(kuò)展包中提供了帶權(quán)重的信號(hào)量?semaphore.Weighted,讓我們可以按照不同的權(quán)重管理資源的訪問(wèn),下面小編就來(lái)和大家聊聊它們的具體用法吧2023-07-07
深入了解Go語(yǔ)言的基本語(yǔ)法與常用函數(shù)
這篇文章主要為大家詳細(xì)介紹一下Go語(yǔ)言中的基本語(yǔ)法與常用函數(shù),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Go語(yǔ)言有一定的幫助,需要的可以參考一下2022-07-07
golang切片擴(kuò)容規(guī)則實(shí)現(xiàn)
這篇文章主要介紹了golang切片擴(kuò)容規(guī)則實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
Go語(yǔ)言基礎(chǔ)for循環(huán)語(yǔ)句的用法及示例詳解
這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)for循環(huán)語(yǔ)句的用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11
Go語(yǔ)言自帶測(cè)試庫(kù)testing使用教程
這篇文章主要為大家介紹了Go語(yǔ)言自帶測(cè)試庫(kù)testing使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07

