脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|shell|

服务器之家 - 脚本之家 - Golang - Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法

Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法

2022-12-25 16:48剑客阿良_ALiang Golang

对音视频一直是小白,决定沉下心来,好好研究一下音视频知识,下面这篇文章主要给大家介绍了关于Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法,需要的朋友可以参考下

前言

最近研究golang音视频处理的时候,试着将mp4推送流媒体服务。下面分享一下代码,大家有需要可以研究一下,按照自己的需求改改。

环境

需要安装:github.com/yapingcat/gomedia

代码

代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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、如果是其他格式的话,可以按照库里其他格式构建。

2、为什么在视频帧推送要睡30ms,可以按照帧率调整,因为读取的速度比较快,会推太快。

执行结果:

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}

拉流画面:

Go语言学习之将mp4通过rtmp推送流媒体服务的实现方法

这个代码主要只是简单的推流,没有太多对视频帧的处理。

如果有需要的话,可以自己集成一些其他的图像处理的库。

可以实现实时的视频处理并推送的功能。

总结

到此这篇关于Go语言学习之将mp4通过rtmp推送流媒体服务实现的文章就介绍到这了,更多相关Go将mp4通过rtmp推送流媒体服务内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/zhiweihongyan1/article/details/128216632

延伸 · 阅读

精彩推荐
  • Golang详解Go语言中关于包导入必学的 8 个知识点

    详解Go语言中关于包导入必学的 8 个知识点

    这篇文章主要介绍了详解Go语言中关于包导入必学的 8 个知识点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需...

    写代码的明哥4952020-08-12
  • GolangGo语言对JSON数据进行序列化和反序列化

    Go语言对JSON数据进行序列化和反序列化

    这篇文章介绍了Go语言对JSON数据进行序列化和反序列化的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的...

    taadis9582022-07-19
  • Golang为 Java 开发者准备的 Go 教程之Java 有而 Go 无

    为 Java 开发者准备的 Go 教程之Java 有而 Go 无

    Go 语言的设计是站在巨人的肩膀上的,它吸取了其他语言的优秀设计,同时摒弃了一些「不认可」的设计。同时,为了保持简单性,Go 的特性也比很多其他...

    polarisxu5982022-01-12
  • Golanggorm+gin实现restful分页接口的实践

    gorm+gin实现restful分页接口的实践

    本文主要介绍了gorm+gin实现restful分页接口的实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    OwenZhang9592022-01-25
  • GolangGO语言实现简单TCP服务的方法

    GO语言实现简单TCP服务的方法

    这篇文章主要介绍了GO语言实现简单TCP服务的方法,实例分析了Go语言实现TCP服务的技巧,需要的朋友可以参考下 ...

    小小的我5392020-04-21
  • Golanggolang 中strings包的Replace的使用说明

    golang 中strings包的Replace的使用说明

    这篇文章主要介绍了golang 中strings包的Replace的使用说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    kph_Hajash11482021-04-20
  • GolangGo语言之init函数

    Go语言之init函数

    Go语言有一个特殊的函数init,先于main函数执行,实现包级别的一些初始化操作。这篇文章介绍了Go中的Init函数,对大家的学习或者工作具有一定的参考学习...

    奋斗的大橙子10692022-07-13
  • Golanggolang操作mongodb的方法

    golang操作mongodb的方法

    这篇文章主要介绍了golang操作mongodb的方法,涉及Go语言操作mongodb的连接、读取及显示的方法,具有一定参考借鉴价值,需要的朋友可以参考下 ...

    脚本之家3242020-04-16