RTMP插件源码解读--奇幻漂流记

RTMP插件源码解读--奇幻漂流记 一、城堡里的“插件门票”第一个任务在城堡Monibuca 框架里开一个叫RTMPPlugin的小店。先写了个牌子结构体type RTMPPlugin struct { pb.UnimplementedApiServer m7s.Plugin // 城堡统一发的营业执照 ChunkSize int default:1024 // 切蛋糕的刀大小默认1024 KeepAlive bool C2 bool }把m7s.Plugin塞进去城堡就承认你是个正规插件了。去城门口登记安装插件var _ m7s.InstallPlugin[RTMPPlugin](m7s.PluginMeta{ DefaultYaml: tcp: listenaddr: :1935, // 在1935号门等客人 ServiceDesc: pb.Api_ServiceDesc, RegisterGRPCHandler: pb.RegisterApiHandler, NewPusher: NewPusher, NewPuller: NewPuller, NewPullProxy: NewPullProxy, NewPushProxy: NewPushProxy, })这就是填表交作业抄模板就行。二、客人敲门1935 号门响了一个主播客户端连了进来。城堡调用刚刚写好的type RTMPServer struct { NetConnection conf *RTMPPlugin } func (p *RTMPPlugin) OnTCPConnect(conn net.Conn) task.ITask { ret : RTMPServer{conf: p} ret.Init(conn) // 拿好客人的手网络连接 ret.Logger p.Logger.With(remote, conn.RemoteAddr().String()) return ret }net.Conn就是一根电话线能听能说。用到了 Go 标准库的net就像接电话不复杂。三、握手与唠嗑循环客人进门先要握手RTMP 协议规定。直接按城堡给的说明书server.Handshake(server.conf.C2) // 握完手才能继续接着搬把椅子循环听客人说话for { cmd, err : server.RecvMessage() // 收到客人的指令 switch cmd.(type) { // 下面分情况招待 } }这就像客服热线客人说一句你回一句。要懂一点“状态机”先连、再建流、再推或播。但代码里已经分好类了。四、客人要连 Wi-Fi客人喊connect需要赶紧回礼case *CallMessage: // connect server.AppName app.(string) // 记住客人要去哪个房间 // 发一堆确认小纸条ACK、块大小、带宽 server.SendMessage(RTMP_MSG_ACK_SIZE, ...) // 最后说“欢迎光临” server.SendMessage(RTMP_MSG_AMF0_COMMAND, m)顺序不能乱像泡茶得先烧水再冲。属于“礼貌流程”背下来就好。五、客人要直播重点来了客人说publishcase *PublishMessage: publisher, err server.conf.Publish(server.Context, 房间名/流名) ns.Writers[cmd.StreamId] struct{...}{Publisher: publisher} ns.BeginPublish(cmd.TransactionId)哦城堡里有个大喇叭Publisher客人说话就把声音接到大喇叭上别人就能听。这里要把 RTMP 的“流”和城堡的“发布者”绑在一起是需要琢磨的最难一点。六、客人要看直播另一个客人说playcase *PlayMessage: suber, err server.conf.Subscribe(server.Context, 房间名/流名) ns.Subscribe(suber)这是反向操作从大喇叭接根线到客人耳机里。和推流对称懂了上一个就懂这个。七、说明书在店门口贴了张纸告诉大家怎么连if port 1935 { p.PushAddr append(p.PushAddr, rtmp://{hostName}/{streamPath}) }默认门牌 1935大家用 rtmp:// 打头就能来。城堡能收直播了不错记住难的东西城堡框架都替你藏好了你只管按流程招呼客人。