go语言版的webrtc h264测试

最近在github上发现了一个go写的webrtc库,心血来潮,下载运行了一下。

1,下载、编译、执行demo

选择play-from-disk这个例子,测试一下从.ivf文件读取vp8帧发送到浏览器

git clone https://github.com/pion/webrtc.git
cd webrtc/examples/play-from-disk
go build

这个时候当前目录下会生成 play-from-disk 可执行文件,在当前目录下放一个output.ivf文件,然后执行 ./play-from-disk 这个时候这个命令行程序等待输入base64编码的sdp

2,启动http服务器

在example目录下运行

go run examples.go
  • 打开 http://127.0.0.1/example/js/play-from-disk/ , 等Browser Session Description 里面生成本地的sdp, 如果没有显示的话,修改一下stun服务器,可能是google stun服务器无法访问
  • 点击 Copy browser Session Description to clipboard 复制浏览器的sdp到粘贴板,在play-from-disk的命令行程序粘贴浏览器sdp,回车 
  • 这个时候play-from-disk也会输出它的sdp, 复制这个sdp 粘贴到浏览器的Remote Session Description输入框中
  • 点击Start Session 按钮,这个时候就可以看到output.ivf的视频内容

至此,一个简单的golang webrtc测试就成功了

3,换一个flv封装的h264视频

官方的demo用的是vp8/vp9 视频文件做测试,那么h264也可以吗?经过一点折腾,确定也是ok的,首先生成一个flv测试文件

ffmpeg -f avfoundation -framerate 30 -pix_fmt yuyv422 -i "0" -vcodec h264 -profile baseline ka.flv

然后改一下main.go 这样play-from-disk可以支持flv h264了

go func() {
	fmt.Println("Wait for connection")
	<-iceConnectedCtx.Done()
	fmt.Println("Wait for connection done")

	f, _ := os.Open("ka.flv")
	d, err := flv.NewDemuxer(f)
	if err == nil {
		fmt.Println("read flv ok")
		defer func() {
			d.Close()
		}()
	}
	ver, v, a, _ := d.ReadHeader()
	fmt.Printf("ver %d has video %v , has audio %v\n", ver, v, a)
	var idx int
	var sps, pps []byte
	ticker := time.NewTicker(time.Millisecond * time.Duration(33))
	for ; true; <-ticker.C {
		tagType, tagSize, _, err := d.ReadTagHeader()
		if err != nil {
			fmt.Println("read done")
			break
		}
		if tagType != 9 {
			d.ReadTag(tagSize)
			continue
		}
		tagData, _ := d.ReadTag(tagSize)
		idx++
		codecId := tagData[0] & 0x0f
		frameType := (tagData[0] & 0xf0) >> 4
		fmt.Printf("[%d] cid %d ft %d pt %d tt %d, ts %d\n", idx, codecId, frameType, tagData[1], tagType, tagSize)
		now := time.Now()

		if tagData[1] == 0 {
			spsLen := tagData[12]
			spsStart := 12 + 1
			ppsLen := tagData[12+1+spsLen+2]
			ppsStart := 12 + 1 + spsLen + 2 + 1
			sps = make([]byte, spsLen)
			pps = make([]byte, ppsLen)
			copy(sps, tagData[spsStart:spsStart+int(spsLen)])
			copy(pps, tagData[ppsStart:int(ppsStart)+int(ppsLen)])
			fmt.Printf("sps len %d, pps len %d\n", spsLen, ppsLen)
		} else {
			naluStart := 5
			if frameType == 1 {
				fmt.Printf("sps len %d, pps len %d\n", len(sps), len(pps))
				videoTrack.WriteSample(media.Sample{Data: sps, Timestamp: now})
				videoTrack.WriteSample(media.Sample{Data: pps, Timestamp: now})
			}
			for {
				naluLen := binary.BigEndian.Uint32(tagData[naluStart : naluStart+4])
				fmt.Printf("nalu len %d\n", naluLen)
				videoTrack.WriteSample(media.Sample{Data: tagData[naluStart+4 : naluStart+4+int(naluLen)], Timestamp: now})
				naluStart += int(naluLen) + 4
				if naluStart >= len(tagData) {
					break
				}
			}
		}
	}
}()

这段代码解析flv文件,提取出h264 nalu 然后通过webrtc发送。h264解析用到了"github.com/ossrs/go-oryx-lib/flv"

4,可能在什么地方有用

由于golang是可以轻松实现交叉编译,这就意味着它可以运行在一些嵌入式linux的环境中,轻松实现webrtc支持。相对于c++版本的webrtc库,这个golang的版本集成起来就很轻松了

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值