pion最简单webrtc例子

更新时间:2023-07-12 07:59:22 阅读: 评论:0

pion最简单webrtc例⼦
鼓励人的名言前⾔
pion是⼀个纯⽤golang写的开源webrtc项⽬,⽬前github上⼤部分webrtc开源都是使⽤c++写的。本⼈认为pion对于⼀个webrtc⼊门者来说golang的语法相对简单,你这样可以更好的关注webrtc协议。如果业务场景不是特别⾼,业务上只做sfu转发服务器的话,可以尝试⽤golang来做。
读这篇⽂章你需要稍微了解webrtc的协议。
例⼦
整体下来就是:
1. 创建peerconnection,设置stun服务器
2. 设置对端的sdp
3. 创建⾃⼰协商的answer,设置answer
4. 等待candidate收集完成,输出序列化后的sdp信息
这边就是⼀个最简单的接受流的例⼦。
package main
import(
"encoding/ba64"
"encoding/json"
"fmt"
"/pion/webrtc/v3"
)
func main(){
//创建pc,并且指定stun服务器
pc, err := webrtc.NewPeerConnection(webrtc.Configuration{
恒悦轩
ICEServers:[]webrtc.ICEServer{
{
怎么克服紧张恐惧心理URLs:[]string{"stun:le.com:19302"},
},
},
})
if err !=nil{
panic(err.Error())
}
sdp := webrtc.SessionDescription{}
//todo:这边需要你⾃⼰设置对端的sdp信息
sdpStr :="eyJ0eXBlIjoib2ZmZXIiLCJzZHAiOiJ2PTBcclxubz0tIDE2OTQ4Nzk1NDc5OTk0ODE3MDYgMiBJTiBJUDQgMTI3LjAuMC4xXHJcbnM9LVxyXG50 PTAgMFxyXG5hPWdyb3VwOkJVTkRMRSAwXHJcbmE9ZXh0bWFwLWFsbG93LW1peGVkXHJcbmE9bXNpZC1zZW1hbnRpYzogV01TIE1PQ0xmd21HT1h wRG41dlB5R3lyZU5nclJ0Y2xQR2xCVmdjSlxyXG5tPXZpZGVvIDUzMzUxIFVEUC9UTFMvUlRQL1NBVlBGIDk2IDk3IDk4IDk5IDEwMCAxMDEgMTAyIDEyM SAxMjcgMTIwIDEyNSAxMDcgMTA4IDEwOSAzNSAzNiAxMjQgMTE5IDEyMyAxMTggMTE0IDExNSAxMTZcclxuYz1JTiBJUDQgNDcuOTEuMjE2LjE5XHJcb mE9cnRjcDo5IElOIElQNCAwLjAuMC4wXHJcbmE9Y2FuZGlkYXRlOjIwOTQwMjg4ODIgMSB1ZHAgMjEyMjI2MDIyMyAxMC4xMDYuMjEyLjc5IDUzMzUxIHR 5cCBob3N0IGdlbmVyYXRpb24gMCBuZXR3b3JrLWlkIDEgbmV0d29yay1jb3N0IDEwXHJcbmE9Y2FuZGlkYXRlOjg0NDM0MjQzNCAxIHRjcCAxNTE4MjgwN DQ3IDEwLjEwNi4yMTIuNzkgOSB0eXAgaG9zdCB0Y3B0eXBlIGFjdGl2ZSBnZW5lcmF0aW9uIDAgbmV0d29yay1pZCAxIG5ldHdvcmstY29zdCAxMFxyXG5h PWNhbmRpZGF0ZTo0MjU0NjIxNDE0IDEgdWRwIDE2ODYwNTI2MDcgNDcuOTEuMjE2LjE5IDUzMzUxIHR5cCBzcmZCByYWRkciAxMC4xMDYuMjEyLjc 5IHJwb3J0IDUzMzUxIGdlbmVyYXRpb24gMCBuZXR3b3JrLWlkIDEgbmV0d29yay1jb3N0IDEwXHJcbmE9aWNlLXVmcmFnOjAxTDJcclxuYT1pY2UtcHdkOjl VOEs4bVp0R0hka0UzK2tHcVl6ODZ4dVxyXG5hPWljZS1vcHRpb25zOnRyaWNrbGVcclxuYT1maW5nZXJwcmludDpzaGEtMjU2IEM1OjM0OjQ4OjlEOjU3Ojl COjhDOkU5OjhCOjI0OjMxOkEwOkIzOjFCOkI1OjJEOjMyOkY0OkJFOjE2OjgxOjhCOjJDOkIyOkFBOjRDOjI5OjI3OkIwOjQ4OjNCOjgxXHJcbmE9c2V0dXA6Y WN0cGFzc1xyXG5hPW1pZDowXHJcbmE9ZXh0bWFwOjEgdXJuOmlldGY6cGFyYW1zOnJ0cC1oZHJleHQ6dG9mZnNldFxyXG5hPWV4dG1hcDoyIGh0dH A6Ly93d3cud2VicnRjLm9yZy9leHBlcmltZW50cy9ydHAtaGRyZXh0L2Ficy1zZW5kLXRpbWVcclxuYT1leHRtYXA6MyB1cm46M2dwcDp2aWRlby1vcmllbnRh dGlvblxyXG5hPWV4dG1hcDo0IGh0dHA6Ly93d3cuaWV0Zi5vcmcvaWQvZHJhZnQtaG9sbWVyLXJtY2F0LXRyYW5zcG9ydC13aWRlLWNjLWV4dGVuc2lvb nMtMDFcclxuYT1leHRtYXA6NSBodHRwOi8vd3d3LndlYnJ0Yy5vcmcvZXhwZXJpbWVudHMvcnRwLWhkcmV4dC9wbGF5b3V0LWRlbGF5XHJcbmE9ZXh0b WFwOjYgaHR0cDovL3d3dy53ZWJydGMub3JnL2V4cGVyaW1lbnRzL3J0cC1oZHJleHQvdmlkZW8tY29udGVudC10eXBlXHJcbmE9ZXh0bWFwOjcgaHR0c
DovL3d3dy53ZWJydGMub3JnL2V4cGVyaW1lbnRzL3J0cC1oZHJleHQvdmlkZW8tdGltaW5nXHJcbmE9ZXh0bWFwOjggaHR0cDovL3d3dy53ZWJydGMub3 JnL2V4cGVyaW1lbnRzL3J0cC1oZHJleHQvY29sb3Itc3BhY2VcclxuYT1leHRtYXA6OSB1cm46aWV0ZjpwYXJhbXM6cnRwLWhkcmV4dDpzZGVzOm1pZFxy
JnL2V4cGVyaW1lbnRzL3J0cC1oZHJleHQvY29sb3Itc3BhY2VcclxuYT1leHRtYXA6OSB1cm46aWV0ZjpwYXJhbXM6cnRwLWhkcmV4dDpzZGVzOm1pZFxy XG5hPWV4dG1hcDoxMCB1cm46aWV0ZjpwYXJhbXM6cnRwLWhkcmV4dDpzZGVzOnJ0cC1zdHJlYW0taWRcclxuYT1leHRtYXA6MTEgdXJuOmlldGY6cGF yYW1zOnJ0cC1oZHJleHQ6c2RlczpyZXBhaXJlZC1ydHAtc3RyZWFtLWlkXHJcbmE9c2VuZHJlY3ZcclxuYT1tc2lkOk1PQ0xmd21HT1hwRG41dlB5R3lyZU5nc lJ0Y2xQR2xCVmdjSiAzMTU2MTk3Ny04MzI3LTQ4MzUtYmNkYi05NTk0MGY0YTE5NWFcclxuYT1ydGNwLW11eFxyXG5hPXJ0Y3AtcnNpemVcclxuYT1ydH BtYXA6OTYgVlA4LzkwMDAwXHJcbmE9cnRjcC1mYjo5NiBnb29nLXJlbWJcclxuYT1ydGNwLWZiOjk2IHRyYW5zcG9ydC1jY1xyXG5hPXJ0Y3AtZmI6OTYgY2 NtIGZpclxyXG5hPXJ0Y3AtZmI6OTYgbmFja1xyXG5hPXJ0Y3AtZmI6OTYgbmFjayBwbGlcclxuYT1ydHBtYXA6OTcgcnR4LzkwMDAwXHJcbmE9Zm10cDo5N yBhcHQ9OTZcclxuYT1ydHBtYXA6OTggVlA5LzkwMDAwXHJcbmE9cnRjcC1mYjo5OCBnb29nLXJlbWJcclxuYT1ydGNwLWZiOjk4IHRyYW5zcG9ydC1jY1xy XG5hPXJ0Y3AtZmI6OTggY2NtIGZpclxyXG5hPXJ0Y3AtZmI6OTggbmFja1xyXG5hPXJ0Y3AtZmI6OTggbmFjayBwbGlcclxuYT1mbXRwOjk4IHByb2ZpbGUt aWQ9MFxyXG5hPXJ0cG1hcDo5OSBydHgvOTAwMDBcclxuYT1mbXRwOjk5IGFwdD05OFxyXG5hPXJ0cG1hcDoxMDAgVlA5LzkwMDAwXHJcbmE9cnRjcC 1mYjoxMDAgZ29vZy1yZW1iXHJcbmE9cnRjcC1mYjoxMDAgdHJhbnNwb3J0LWNjXHJcbmE9cnRjcC1mYjoxMDAgY2NtIGZpclxyXG5hPXJ0Y3AtZmI6MTAw IG5hY2tcclxuYT1ydGNwLWZiOjEwMCBuYWNrIHBsaVxyXG5hPWZtdHA6MTAwIHByb2ZpbGUtaWQ9MlxyXG5hPXJ0cG1hcDoxMDEgcnR4LzkwMDAwXHJ cbmE9Zm10cDoxMDEgYXB0PTEwMFxyXG5hPXJ0cG1hcDoxMDIgSDI2NC85MDAwMFxyXG5hPXJ0Y3AtZmI6MTAyIGdvb2ctcmVtYlxyXG5hPXJ0Y3AtZmI 6MTAyIHRyYW5zcG9ydC1jY1xyXG5hPXJ0Y3AtZmI6MTAyIGNjbSBmaXJcclxuYT1ydGNwLWZiOjEwMiBuYWNrXHJcbmE9cnRjcC1mYjoxMDIgbmFjayBwb GlcclxuYT1mbXRwOjEwMiBsZXZlbC1hc3ltbWV0cnktYWxsb3dlZD0xO3BhY2tldGl6YXRpb24tbW9kZT0xO3Byb2ZpbGUtbGV2ZWwtaWQ9NDIwMDFmXHJc
bmE9cnRwbWFwOjEyMSBydHgvOTAwMDBcclxuYT1mbXRwOjEyMSBhcHQ9MTAyXHJcbmE9cnRwbWFwOjEyNyBIMjY0LzkwMDAwXHJcbmE9cnRjcC1m YjoxMjcgZ29vZy1yZW1iXHJcbmE9cnRjcC1mYjoxMjcgdHJhbnNwb3J0LWNjXHJcbmE9cnRjcC1mYjoxMjcgY2NtIGZpclxyXG5hPXJ0Y3AtZmI6MTI3IG5hY2t cclxuYT1ydGNwLWZiOjEyNyBuYWNrIHBsaVxyXG5hPWZtdHA6MTI3IGxldmVsLWFzeW1tZXRyeS1hbGxvd2VkPTE7cGFja2V0aXphdGlvbi1tb2RlPTA7cHJv ZmlsZS1sZXZlbC1pZD00MjAwMWZcclxuYT1ydHBtYXA6MTIwIHJ0eC85MDAwMFxyXG5hPWZtdHA6MTIwIGFwdD0xMjdcclxuYT1ydHBtYXA6MTI1IEgyNj QvOTAwMDBcclxuYT1ydGNwLWZiOjEyNSBnb29nLXJlbWJcclxuYT1ydGNwLWZiOjEyNSB0cmFuc3BvcnQtY2NcclxuYT1ydGNwLWZiOjEyNSBjY20gZmlyX HJcbmE9cnRjcC1mYjoxMjUgbmFja1xyXG5hPXJ0Y3AtZmI6MTI1IG5hY2sgcGxpXHJcbmE9Zm10cDoxMjUgbGV2ZWwtYXN5bW1ldHJ5LWFsbG93ZWQ9M TtwYWNrZXRpemF0aW9uLW1vZGU9MTtwcm9maWxlLWxldmVsLWlkPTQyZTAxZlxyXG5hPXJ0cG1hcDoxMDcgcnR4LzkwMDAwXHJcbmE9Zm10cDoxM DcgYXB0PTEyNVxyXG5hPXJ0cG1hcDoxMDggSDI2NC85MDAwMFxyXG5hPXJ0Y3AtZmI6MTA4IGdvb2ctcmVtYlxyXG5hPXJ0Y3AtZmI6MTA4IHRyYW5zc G9ydC1jY1xyXG5hPXJ0Y3AtZmI6MTA4IGNjbSBmaXJcclxuYT1ydGNwLWZiOjEwOCBuYWNrXHJcbmE9cnRjcC1mYjoxMDggbmFjayBwbGlcclxuYT1mbXR wOjEwOCBsZXZlbC1hc3ltbWV0cnktYWxsb3dlZD0xO3BhY2tldGl6YXRpb24tbW9kZT0wO3Byb2ZpbGUtbGV2ZWwtaWQ9NDJlMDFmXHJcbmE9cnRwbWF wOjEwOSBydHgvOTAwMDBcclxuYT1mbXRwOjEwOSBhcHQ9MTA4XHJcbmE9cnRwbWFwOjM1IEFWMVgvOTAwMDBcclxuYT1ydGNwLWZiOjM1IGdvb2c tcmVtYlxyXG5hPXJ0Y3AtZmI6MzUgdHJhbnNwb3J0LWNjXHJcbmE9cnRjcC1mYjozNSBjY20gZmlyXHJcbmE9cnRjcC1mYjozNSBuYWNrXHJcbmE9cnRjcC1 mYjozNSBuYWNrIHBsaVxyXG5hPXJ0cG1hcDozNiBydHgvOTAwMDBcclxuYT1mbXRwOjM2IGFwdD0zNVxyXG5hPXJ0cG1hcDoxMjQgSDI2NC85MDAwMF xyXG5hPXJ0Y3AtZmI6MTI0IGdvb2ctcmVtYlxyXG5hPXJ0Y3AtZmI6MTI0IHRyYW5zcG9ydC1jY1xyXG5hPXJ0Y3AtZmI6MTI0IGNjbSBmaXJcclxuYT1ydGNw LWZiOjEyNCBuYWNrXHJcbmE9cnRjcC1mYjoxMjQgbmFjayBwbGlcclxuYT1mbXRwOjEyNCBsZXZlbC1hc3ltbWV0cnktYWxsb3dlZD0xO3BhY2tldGl6YXRpb 24tbW9kZT0xO3Byb2ZpbGUtbGV2ZWwtaWQ9NGQwMDMyXHJcbmE9cnRwbWFwOjExOSBydHgvOTAwMDBcclxuYT1mbXRwOjExOSBhcHQ9MTI0XHJc bmE9cnRwbWFwOjEyMyBIMjY0LzkwMDAwXHJcbmE9cnRjcC1mYjoxMjMgZ29vZy1yZW1iXHJcbmE9cnRjcC1mYjoxMjMgdHJhbnNwb3J0LWNjXHJcbmE9c
nRjcC1mYjoxMjMgY2NtIGZpclxyXG5hPXJ0Y3AtZmI6MTIzIG5hY2tcclxuYT1ydGNwLWZiOjEyMyBuYWNrIHBsaVxyXG5hPWZtdHA6MTIzIGxldmVsLWFze W1tZXRyeS1hbGxvd2VkPTE7cGFja2V0aXphdGlvbi1tb2RlPTE7cHJvZmlsZS1sZXZlbC1pZD02NDAwMzJcclxuYT1ydHBtYXA6MTE4IHJ0eC85MDAwMFxy XG5hPWZtdHA6MTE4IGFwdD0xMjNcclxuYT1ydHBtYXA6MTE0IHJlZC85MDAwMFxyXG5hPXJ0cG1hcDoxMTUgcnR4LzkwMDAwXHJcbmE9Zm10cDoxMT UgYXB0PTExNFxyXG5hPXJ0cG1hcDoxMTYgdWxwZmVjLzkwMDAwXHJcbmE9c3NyYy1ncm91cDpGSUQgMjY2MjI0MzgzNiAxMDM2NTM2NTlcclxuYT1zc 3JjOjI2NjIyNDM4MzYgY25hbWU6STk3MEs2VDVSWGZHRkRxaFxyXG5hPXNzcmM6MjY2MjI0MzgzNiBtc2lkOk1PQ0xmd21HT1hwRG41dlB5R3lyZU5nclJ0 Y2xQR2xCVmdjSiAzMTU2MTk3Ny04MzI3LTQ4MzUtYmNkYi05NTk0MGY0YTE5NWFcclxuYT1zc3JjOjI2NjIyNDM4MzYgbXNsYWJlbDpNT0NMZndtR09Yc ERuNXZQeUd5cmVOZ3JSdGNsUEdsQlZnY0pcclxuYT1zc3JjOjI2NjIyNDM4MzYgbGFiZWw6MzE1NjE5NzctODMyNy00ODM1LWJjZGItOTU5NDBmNGExO TVhXHJcbmE9c3NyYzoxMDM2NTM2NTkgY25hbWU6STk3MEs2VDVSWGZHRkRxaFxyXG5hPXNzcmM6MTAzNjUzNjU5IG1zaWQ6TU9DTGZ3bUdPWHB EbjV2UHlHeXJlTmdyUnRjbFBHbEJWZ2NKIDMxNTYxOTc3LTgzMjctNDgzNS1iY2RiLTk1OTQwZjRhMTk1YVxyXG5hPXNzcmM6MTAzNjUzNjU5IG1zbGFiZ Ww6TU9DTGZ3bUdPWHBEbjV2UHlHeXJlTmdyUnRjbFBHbEJWZ2NKXHJcbmE9c3NyYzoxMDM2NTM2NTkgbGFiZWw6MzE1NjE5NzctODMyNy00ODM1L WJjZGItOTU5NDBmNGExOTVhXHJcbiJ9"
//前端页⾯会对sdp进⾏ba64的encode
b, err := ba64.StdEncoding.DecodeString(sdpStr)
if err !=nil{
panic(err)
}
//反序列化为sdp
if err = json.Unmarshal(b,&sdp); err !=nil{
panic(err.Error())
}
//设置远端的sdp
if err = pc.SetRemoteDescription(sdp); err !=nil{
panic(err.Error())
}
//创建协商结果
answer, err := pc.CreateAnswer(nil)
if err !=nil{
panic(err.Error())
}
//设置⾃⼰的协商结果
if err = pc.SetLocalDescription(answer); err !=nil{
panic(err)
}
//等待ice结束
gatherCmp := webrtc.GatheringCompletePromi(pc)
gatherCmp := webrtc.GatheringCompletePromi(pc)
<-gatherCmp
/
/将协商并且收集完candidate的answer,输出到控制台
answerBytes, err := json.Marshal(*pc.LocalDescription())
if err !=nil{
panic(err)
}
/*
//这段代码可以省略,也可以放开。他可以清楚的让你知道你是否推流成功
pc.OnTrack(func(remote *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {      fmt.Println("one track = ", remote.PayloadType())
rtpBuf := make([]byte, 1400)
for {
n, as, err := remote.Read(rtpBuf)
fmt.Println("n = ", n, "  as = ", as, " err = ", err)定风
}
})
*/
fmt.Println(ba64.StdEncoding.EncodeToString(answerBytes))
lect{
}
}
流程
创建peerconnection
⼀开始我们需要创建⼀个peerconnection,这个会接受配置信息如下:
type Configuration struct{
//stun或者turn服务器信息,为空只会有host
ICEServers []ICEServer `json:"iceServers,omitempty"`
//这个会规定
//ICETransportPolicyAll 会收集所有的candidate,默认
//ICETransportPolicyRelay 只会收集relay的candidate双赢英语
ICETransportPolicy ICETransportPolicy `json:"iceTransportPolicy,omitempty"`
//BundlePolicyBalanced 相当于“balanced“,这种情况下⾳频和视频只会建⽴两个传输的通道进⾏传输。如果对端不⽀持这种⽅式,那么会将各个轨道的⾳频分开。默认
//BundlePolicyMaxCompat 相当于“max-compat”,这种情况下会将所有的媒体轨道分开不同的通道做传输,⾳频可能会有多条通道传输,视频可能⼀条。如果对端不⽀持blanced会回退到这种模式。
问题生//BundlePolicyMaxBundle 相当于“max-bundle”,这种情况下会将所有的媒体只放到⼀个通道传输。如
果对端不⽀持单通道,可能会有丢失媒体轨道。
BundlePolicy BundlePolicy `json:"bundlePolicy,omitempty"`
//RTCPMuxPolicyNegotiate rtp和rtcp是否复⽤⼀个candidate,可以经过协商后得到。如果对端⽀持端⼝复⽤,那么就共⽤⼀个candidate。如果对端不⽀持⼀个candidate,那么就分开。默认。
幼儿园英语教学//RTCPMuxPolicyRequire rtp和rtcp必须要复⽤⼀个candidate,否则会失败
RTCPMuxPolicy RTCPMuxPolicy `json:"rtcpMuxPolicy,omitempty"`
//对端的⾝份标⽰,默认为空。
PeerIdentity string`json:"peerIdentity,omitempty"`
//DTLS建⽴时的证书,如果没有填,会⾃⼰⽣成。
Certificates []Certificate `json:"certificates,omitempty"`
//当指定⼤⼩会提前去收集size个candidate供你使⽤,就不⽤等到tLocalDescription()再去收集。默认是0。
ICECandidatePoolSize uint8`json:"iceCandidatePoolSize,omitempty"`
//sdp交互的格式,以下3种值。
//SDPSemanticsUnifiedPlan sdp的格式为unified plan
//SDPSemanticsPlanB sdp格式为plan b
//SDPSemanticsUnifiedPlanWithFallback 取决于offer的格式,如果unified plan会会unified plan,如果是plan b会回plan b
SDPSemantics SDPSemantics `json:"sdpSemantics,omitempty"`
进步的反义词}
webrtc.NewPeerConnection函数会去初始化⼀些配置,做nack的处理等。
设置对端的sdp
sdp信息我们没有经过信令服务器做转发,做了⼀个最朴素的⽅法,直接写到代码⾥⾯,通过反序列化后直接SetRemoteDescription到pc 中。pc会和默认⽀持的code做协商、设置remote Candidate、开
始调⽤ICE的联通性检查等操作。但是值得注意的是,真正开始连通性检查时需要双端的candidate都有。
创建、设置answer
这个时候会根据协商的内容,创建不同的媒体流,并且在设置的时候会开始收集信息⾃⼰的candidate。
输出最终answer
在SetLocalDescription的时候会开始收集,gatherCmp管道会在收集完成的时候收到内容。当收集完成我们就可以将本地的Candidate 发送到远端。当然现在已经有ticker ice了,并不需要全部收集完成再发送,我们这边为了简单⽤的还是⽐较旧的⽅式。当我们收集完Candidate,这个时候就可以将本地的sdp经过序列化发送给远端了,剩下的就是连通性检查,然后推流了。

本文发布于:2023-07-12 07:59:22,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1092221.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:收集   完成   格式
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图