最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語(yǔ)言學(xué)習(xí)之將mp4通過(guò)rtmp推送流媒體服務(wù)的實(shí)現(xiàn)方法

 更新時(shí)間:2022年12月24日 14:04:29   作者:劍客阿良_ALiang  
對(duì)音視頻一直是小白,決定沉下心來(lái),好好研究一下音視頻知識(shí),下面這篇文章主要給大家介紹了關(guān)于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語(yǔ)言實(shí)現(xiàn)AES加密的方法

    go語(yǔ)言實(shí)現(xiàn)AES加密的方法

    這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)AES加密的方法,實(shí)例分析了Go語(yǔ)言的加密技巧,需要的朋友可以參考下
    2015-03-03
  • Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀

    這篇文章主要為大家介紹了Go channel發(fā)送方和接收方如何相互阻塞等待源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Go 并發(fā)讀寫(xiě) sync.map 詳細(xì)

    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使用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ò)展原語(yǔ)之Semaphore的用法詳解

    Go語(yǔ)言的擴(kuò)展包中提供了帶權(quán)重的信號(hào)量?semaphore.Weighted,讓我們可以按照不同的權(quán)重管理資源的訪問(wèn),下面小編就來(lái)和大家聊聊它們的具體用法吧
    2023-07-07
  • 深入了解Go語(yǔ)言的基本語(yǔ)法與常用函數(shù)

    深入了解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)

    這篇文章主要介紹了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ǔ)句的用法及示例詳解

    這篇文章主要為大家介紹了Go語(yǔ)言基礎(chǔ)for循環(huán)語(yǔ)句的用法及示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2021-11-11
  • Go字典使用詳解

    Go字典使用詳解

    今天和大家一起學(xué)習(xí)Go語(yǔ)言的字典。Go語(yǔ)言的字典又稱為map,一種使用廣泛的數(shù)據(jù)結(jié)構(gòu)。它是擁有key/value對(duì)元素的「無(wú)序集合」,而且在集合中key必須是唯一的
    2022-11-11
  • Go語(yǔ)言自帶測(cè)試庫(kù)testing使用教程

    Go語(yǔ)言自帶測(cè)試庫(kù)testing使用教程

    這篇文章主要為大家介紹了Go語(yǔ)言自帶測(cè)試庫(kù)testing使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07

最新評(píng)論

曲靖市| 珲春市| 长沙县| 蓝山县| 西昌市| 芒康县| 桐乡市| 梧州市| 集安市| 焉耆| 奉化市| 高青县| 阿克苏市| 罗定市| 大宁县| 临高县| 衡东县| 清远市| 边坝县| 常德市| 浑源县| 肇庆市| 綦江县| 岳阳县| 石泉县| 铁岭县| 高雄市| 简阳市| 温宿县| 电白县| 曲水县| 石台县| 阳山县| 宁化县| 红河县| 阜新市| 甘孜| 电白县| 五峰| 晴隆县| 屏东县|