From ea92f41137a1fec6ba86acefc9e3977064947ef9 Mon Sep 17 00:00:00 2001 From: ydajiang Date: Thu, 17 Jul 2025 09:59:30 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81G726=E7=BC=96?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gb28181/publish_test.go | 7 +++-- go.mod | 3 +- jt1078/jt_demuxer.go | 2 +- jt1078/jt_packet.go | 4 +-- jt1078/jt_test.go | 55 ++++++++++++++++++++++++++++++++++- transcode/audio_transcoder.go | 34 ++++++++++++++++++++++ 6 files changed, 98 insertions(+), 7 deletions(-) diff --git a/gb28181/publish_test.go b/gb28181/publish_test.go index a7c534f..d660c5b 100644 --- a/gb28181/publish_test.go +++ b/gb28181/publish_test.go @@ -206,8 +206,11 @@ func TestPublish(t *testing.T) { //path := "../../source_files/rtp_ps_h264_pcm32k_0xBEBC207.raw" //var rawSsrc uint32 = 0xBEBC207 - path := "../../source_files/rtp_ps_h264_G7221_0xBEBC204.raw" - var rawSsrc uint32 = 0xBEBC204 + //path := "../../source_files/rtp_ps_h264_G7221_0xBEBC204.raw" + //var rawSsrc uint32 = 0xBEBC204 + + path := "../../source_files/rtp_ps_h264_G726_0xBEBC205.raw" + var rawSsrc uint32 = 0xBEBC205 localAddr := "0.0.0.0:20001" id := "hls_mystream" diff --git a/go.mod b/go.mod index 708f272..7fd3914 100644 --- a/go.mod +++ b/go.mod @@ -1,7 +1,7 @@ module github.com/lkmio/lkm require ( - github.com/lkmio/audio-transcoder v0.0.0-20250702123727-6c54138868c6 + github.com/lkmio/audio-transcoder v0.2.1 github.com/lkmio/flv v0.0.0 github.com/lkmio/mpeg v0.0.0 github.com/lkmio/rtmp v0.0.0 @@ -28,6 +28,7 @@ require ( github.com/BurntSushi/toml v1.3.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/google/uuid v1.3.1 // indirect + github.com/lkmio/g726 v0.1.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.16 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect diff --git a/jt1078/jt_demuxer.go b/jt1078/jt_demuxer.go index 226be6a..31c33c1 100644 --- a/jt1078/jt_demuxer.go +++ b/jt1078/jt_demuxer.go @@ -37,7 +37,7 @@ func (d *Demuxer) ProcessPrevPacket() error { } if !d.Completed && d.Tracks.Size() > 1 { - d.ProbeComplete() + d.TryCompleteProbe() } return nil } diff --git a/jt1078/jt_packet.go b/jt1078/jt_packet.go index 8b6d967..daa9ad7 100644 --- a/jt1078/jt_packet.go +++ b/jt1078/jt_packet.go @@ -146,8 +146,8 @@ func PT2CodecID(pt byte) (error, utils.AVCodecID) { return nil, utils.AVCodecIdPCMMULAW case PTAudioAAC: return nil, utils.AVCodecIdAAC - //case PTAudioADPCMA: - // return nil, utils.AVCodecIdADPCMAFC + case PTAudioG726: + return nil, utils.AVCodecIdADPCMG726 default: return fmt.Errorf("the codec %d is not implemented", pt), utils.AVCodecIdNONE } diff --git a/jt1078/jt_test.go b/jt1078/jt_test.go index 9a1993e..78794f8 100644 --- a/jt1078/jt_test.go +++ b/jt1078/jt_test.go @@ -166,8 +166,61 @@ func TestPublish(t *testing.T) { }) + t.Run("decode_1078_raw", func(t *testing.T) { + //path := "../../source_files/0714-1.bin" + path := "../../source_files/013800138000-1.bin" + data, err := os.ReadFile(path) + + if err != nil { + panic(err) + } + + os.Remove(path + ".video") + os.Remove(path + ".audio") + + delimiter := [4]byte{0x30, 0x31, 0x63, 0x64} + decoder := transport.NewDelimiterFrameDecoder(1024*1024*2, delimiter[:]) + + length := len(data) + for n := 0; n < length; { + i, bytes, err := decoder.Input(data[n:]) + if err != nil { + panic(err) + } else if len(bytes) < 1 { + break + } + + n += i + packet := Packet{} + err = packet.Unmarshal(bytes) + if err != nil { + panic(err) + } + + if packet.packetType < AudioFrameMark { + f, err := os.OpenFile(path+".video", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + panic(err) + } + + f.Write(packet.payload) + f.Close() + } else if packet.packetType == AudioFrameMark { + f, err := os.OpenFile(path+".audio", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + panic(err) + } + + f.Write(packet.payload) + f.Close() + } + } + }) + t.Run("publish", func(t *testing.T) { - path := "../../source_files/10352264314-2.bin" + //path := "../../source_files/10352264314-2.bin" + //path := "../../source_files/013800138000-1.bin" + path := "../../source_files/0714-1.bin" publish(path, "1078") }) diff --git a/transcode/audio_transcoder.go b/transcode/audio_transcoder.go index fc022aa..fdd247f 100644 --- a/transcode/audio_transcoder.go +++ b/transcode/audio_transcoder.go @@ -8,6 +8,7 @@ import ( audio_transcoder "github.com/lkmio/audio-transcoder" "github.com/lkmio/avformat" "github.com/lkmio/avformat/utils" + "github.com/lkmio/g726" ) func init() { @@ -60,6 +61,20 @@ func (t *AudioTranscoder) GetEncoderID() utils.AVCodecID { return t.encoderID } +func bitRate2G726Rate(bitRate int) (g726.G726Rate, error) { + if bitRate <= 16000 { + return g726.G726Rate16kbps, nil + } else if bitRate <= 24000 { + return g726.G726Rate24kbps, nil + } else if bitRate <= 32000 { + return g726.G726Rate32kbps, nil + } else if bitRate <= 40000 { + return g726.G726Rate40kbps, nil + } else { + return g726.G726Rate(-1), fmt.Errorf("unsupported bit rate: %d", bitRate) + } +} + func NewAudioTranscoder(src *avformat.AVStream, dst []utils.AVCodecID) (Transcoder, *avformat.AVStream, error) { var err error var decoder audio_transcoder.Decoder @@ -115,6 +130,15 @@ func NewAudioTranscoder(src *avformat.AVStream, dst []utils.AVCodecID) (Transcod return nil, nil, err } break + case utils.AVCodecIdADPCMG726: + var rate g726.G726Rate + rate, err = bitRate2G726Rate(src.BitRate) + if err != nil { + return nil, nil, err + } else if err = decoder.(*audio_transcoder.G726Decoder).Create(rate); err != nil { + return nil, nil, err + } + break } } @@ -131,6 +155,16 @@ func NewAudioTranscoder(src *avformat.AVStream, dst []utils.AVCodecID) (Transcod if _, err = encoder.(*audio_transcoder.OpusEncoder).Create(src.SampleRate, src.Channels); err != nil { return nil, nil, err } + break + case utils.AVCodecIdADPCMG726: + var rate g726.G726Rate + rate, err = bitRate2G726Rate(src.BitRate) + if err != nil { + return nil, nil, err + } else if err = encoder.(*audio_transcoder.G726Encoder).Create(rate); err != nil { + return nil, nil, err + } + break } dstStream := &avformat.AVStream{}