mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-10-22 11:19:24 +08:00

格式 - 按需拉流的事件的类型从`*Stream`修改为`InvitePublish` - 远程拉流频繁重连后导致多路远程流同时写入同一个`track` - 在并发序列化`Tracks`时导致错误,通过加锁解决 - 修复`Record`插件录制`fmp4`格式报错 - 更新`WebRTC`插件依赖库版本 - 更新依赖库`quic-go`版本 - 优化`ps`插件中的`tcp`收流逻辑 - 优化`rtmp`插件streamId计算方法
124 lines
2.7 KiB
Go
124 lines
2.7 KiB
Go
package test
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
. "m7s.live/engine/v4"
|
|
"m7s.live/engine/v4/config"
|
|
"m7s.live/engine/v4/track"
|
|
"m7s.live/engine/v4/util"
|
|
)
|
|
|
|
var conf UnitTestConfig
|
|
var unitTestPlugin = InstallPlugin(&conf)
|
|
var spsppsbase64 = "AAABJ2QANKwTGqAoALWgHixLcAAAAAEozgVywA=="
|
|
var spspps, _ = base64.RawStdEncoding.DecodeString(spsppsbase64)
|
|
var EngineChan = make(chan int, 10)
|
|
var WaitEngine sync.WaitGroup
|
|
|
|
func UseEngine() {
|
|
EngineChan <- 1
|
|
WaitEngine.Wait()
|
|
}
|
|
func FreeEngine() {
|
|
EngineChan <- -1
|
|
}
|
|
func init() {
|
|
WaitEngine.Add(1)
|
|
go func() {
|
|
var use = 0
|
|
bg := context.Background()
|
|
var ctx context.Context
|
|
var cancel context.CancelFunc
|
|
for {
|
|
select {
|
|
case delta := <-EngineChan:
|
|
use += delta
|
|
switch use {
|
|
case 1:
|
|
ctx, cancel = context.WithTimeout(bg, time.Second*20)
|
|
go Run(ctx, "config.yaml")
|
|
case 0:
|
|
cancel()
|
|
WaitEngine.Add(1)
|
|
}
|
|
}
|
|
}
|
|
}()
|
|
}
|
|
|
|
type UnitTestConfig struct {
|
|
config.Subscribe
|
|
config.Publish
|
|
}
|
|
|
|
func (t *UnitTestConfig) OnEvent(event any) {
|
|
switch event.(type) {
|
|
case FirstConfig:
|
|
WaitEngine.Done()
|
|
}
|
|
}
|
|
|
|
type UnitTestPublisher struct {
|
|
tb testing.TB
|
|
Publisher
|
|
}
|
|
|
|
type UnitTestSubsciber struct {
|
|
tb testing.TB
|
|
Subscriber
|
|
}
|
|
|
|
func (s *UnitTestSubsciber) OnEvent(event any) {
|
|
switch v := event.(type) {
|
|
case AudioFrame:
|
|
case VideoFrame:
|
|
b := v.AUList.ToBytes()
|
|
seq := (uint16(b[1]) << 8) | uint16(b[2])
|
|
// s.Trace("sequence", zap.Uint32("sequence", v.Sequence), zap.Uint16("seq", seq), zap.Int("len", len(b)))
|
|
if v.Sequence != uint32(seq) {
|
|
s.tb.Fatal("sequence error", v.Sequence, seq)
|
|
}
|
|
default:
|
|
s.Subscriber.OnEvent(event)
|
|
}
|
|
}
|
|
|
|
func (pub *UnitTestPublisher) OnEvent(event any) {
|
|
switch event.(type) {
|
|
case IPublisher:
|
|
pub.VideoTrack = track.NewH264(pub.Stream)
|
|
pub.VideoTrack.WriteAnnexB(0, 0, spspps)
|
|
pub.AudioTrack = track.NewAAC(pub.Stream)
|
|
go pub.WriteAudio()
|
|
go pub.WriteVideo()
|
|
}
|
|
}
|
|
func (pub *UnitTestPublisher) WriteAudio() {
|
|
for i := uint32(0); pub.Err() == nil; i++ {
|
|
time.Sleep(40 * time.Millisecond)
|
|
elapse := time.Since(pub.StartTime)
|
|
pts := uint32(elapse.Milliseconds() * 90)
|
|
pub.AudioTrack.WriteADTS(pts, util.Buffer([]byte{0xFF, 0xE1, 0x20, 0x00, 0x29, 0xA7, 0xF0, byte(i >> 8), byte(i), 0}))
|
|
}
|
|
}
|
|
func (pub *UnitTestPublisher) WriteVideo() {
|
|
for i := uint32(0); pub.Err() == nil; i++ {
|
|
time.Sleep(40 * time.Millisecond)
|
|
elapse := time.Since(pub.StartTime)
|
|
pts := uint32(elapse.Milliseconds() * 90)
|
|
var naluType byte = 0x61
|
|
if elapse%8 == 0 {
|
|
naluType = 0x65
|
|
}
|
|
data := []byte{naluType, byte(i >> 8), byte(i)}
|
|
pub.Trace("data", zap.Uint32("i", i))
|
|
pub.VideoTrack.WriteNalu(pts, pts, data)
|
|
}
|
|
}
|