From 7efcbb200fc4f5e60d42fa1aa36594b588189912 Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:25:28 +0200 Subject: [PATCH 1/8] fix: add crypto tag to log --- zoom/codecs/h264/video_depacketizer.go | 4 ++-- zoom/codecs/opus/audio_depacketizer.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/zoom/codecs/h264/video_depacketizer.go b/zoom/codecs/h264/video_depacketizer.go index 3b3ba67..696f709 100644 --- a/zoom/codecs/h264/video_depacketizer.go +++ b/zoom/codecs/h264/video_depacketizer.go @@ -37,13 +37,13 @@ func (depacketizer *VideoDepacketizer) Unmarshal(packet []byte) ([]byte, error) } // 4. Decrypt the ciphertext - log.Printf("body iv=%v body=%v tag=%v", hex.EncodeToString(decodedPayload.IV), hex.EncodeToString(decodedPayload.Ciphertext), hex.EncodeToString(decodedPayload.Tag)) + log.Printf("crypto: body iv=%v body=%v tag=%v", hex.EncodeToString(decodedPayload.IV), hex.EncodeToString(decodedPayload.Ciphertext), hex.EncodeToString(decodedPayload.Tag)) ciphertextWithTag := append(decodedPayload.Ciphertext, decodedPayload.Tag...) plaintext, err := depacketizer.decryptor.Decrypt(decodedPayload.IV, ciphertextWithTag) if err != nil { return nil, err } - log.Printf("rtp: decrypted=%v", hex.EncodeToString(plaintext)) + log.Printf("crypto: decrypted=%v", hex.EncodeToString(plaintext)) return plaintext, nil } else { diff --git a/zoom/codecs/opus/audio_depacketizer.go b/zoom/codecs/opus/audio_depacketizer.go index 7db24b2..598ba9b 100644 --- a/zoom/codecs/opus/audio_depacketizer.go +++ b/zoom/codecs/opus/audio_depacketizer.go @@ -27,13 +27,13 @@ func (depacketizer *AudioDepacketizer) Unmarshal(packet []byte) ([]byte, error) } // 2. Decrypt the ciphertext - log.Printf("body iv=%v body=%v tag=%v", hex.EncodeToString(decodedPayload.IV), hex.EncodeToString(decodedPayload.Ciphertext), hex.EncodeToString(decodedPayload.Tag)) + log.Printf("crypto: body iv=%v body=%v tag=%v", hex.EncodeToString(decodedPayload.IV), hex.EncodeToString(decodedPayload.Ciphertext), hex.EncodeToString(decodedPayload.Tag)) ciphertextWithTag := append(decodedPayload.Ciphertext, decodedPayload.Tag...) plaintext, err := depacketizer.decryptor.Decrypt(decodedPayload.IV, ciphertextWithTag) if err != nil { return nil, err } - log.Printf("rtp: decrypted=%v", hex.EncodeToString(plaintext)) + log.Printf("crypto: decrypted=%v", hex.EncodeToString(plaintext)) return plaintext, nil } From 2980f49647d506e76cf5db93cd413bb932b5cefa Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:26:24 +0200 Subject: [PATCH 2/8] feat: add MP4 recorder --- zoom/formats/h264raw/muxer.go | 17 +++++ zoom/formats/mp4/muxer.go | 123 ++++++++++++++++++++++++++++++++++ zoom/streams.go | 26 +++---- 3 files changed, 151 insertions(+), 15 deletions(-) create mode 100644 zoom/formats/h264raw/muxer.go create mode 100644 zoom/formats/mp4/muxer.go diff --git a/zoom/formats/h264raw/muxer.go b/zoom/formats/h264raw/muxer.go new file mode 100644 index 0000000..7f2f85c --- /dev/null +++ b/zoom/formats/h264raw/muxer.go @@ -0,0 +1,17 @@ +package h264raw + +import ( + "io" + "os" + "time" +) + +func Recorder() (io.WriteCloser, error) { + f, err := os.Create(time.Now().Format("2006-01-02-15-04-05") + ".h264") + if err != nil { + return nil, err + } + return f, nil + // defer f.Close() + // n2, err := f.Write(d2) +} diff --git a/zoom/formats/mp4/muxer.go b/zoom/formats/mp4/muxer.go new file mode 100644 index 0000000..85818b3 --- /dev/null +++ b/zoom/formats/mp4/muxer.go @@ -0,0 +1,123 @@ +package mp4 + +import ( + "encoding/hex" + "fmt" + "log" + "time" + + "github.com/RealKeyboardWarrior/joy4/av" + "github.com/RealKeyboardWarrior/joy4/av/avutil" + "github.com/RealKeyboardWarrior/joy4/codec/h264parser" + "github.com/RealKeyboardWarrior/joy4/format" +) + +func init() { + format.RegisterAll() +} + +type Mp4Recorder struct { + muxer av.MuxCloser + initialized bool + prevDuration time.Duration +} + +func NewRecorder() (*Mp4Recorder, error) { + muxer, err := avutil.Create(time.Now().Format("2006-01-02-15-04-05") + ".fmp4") + if err != nil { + return nil, err + } + + log.Printf("Mp4Recorder: starting") + return &Mp4Recorder{ + muxer: muxer, + initialized: false, + prevDuration: time.Duration(0), + }, nil +} + +func (recorder *Mp4Recorder) tryInitialize(nalus []byte) error { + codec, err := h264parser.PktToCodecData(av.Packet{ + IsKeyFrame: true, + Data: nalus, + }) + if err != nil { + return err + } + if codec == nil { + return fmt.Errorf("failed to initialize muxer because no codec data was extracted from nalus") + } + + codecs := []av.CodecData{codec} + if err = recorder.muxer.WriteHeader(codecs); err != nil { + return err + } + + recorder.initialized = true + return nil +} + +func IsKeyFrame(naluz []byte) bool { + nalus, _ := h264parser.SplitNALUs(naluz) + log.Printf("Mp4Recorder: processing %v nalus", len(nalus)) + for _, nalu := range nalus { + if len(nalu) > 0 { + naltype := nalu[0] & 0x1f + if naltype == 5 { + return true + } + } + } + return false +} + +func (recorder *Mp4Recorder) WritePacket(nalus []byte, duration time.Duration) error { + if !recorder.initialized { + if err := recorder.tryInitialize(nalus); err != nil { + log.Printf("Mp4Recorder: failed to initialize with packet") + return nil + } else { + log.Printf("Mp4Recorder: initialized") + } + } + + log.Printf("Mp4Recorder: writing packet") + isKeyFrame := IsKeyFrame(nalus) + avccBytes, err := h264parser.AnnexBToAVCC(nalus) + if err != nil { + return err + } + + if avccBytes == nil { + log.Printf("skipping writing packet, conversion to AVCC yielded no VCL units in %v", hex.EncodeToString(nalus)) + return nil + } + + recorder.prevDuration = recorder.prevDuration + duration + err = recorder.muxer.WritePacket(av.Packet{ + IsKeyFrame: isKeyFrame, + Idx: int8(0), + CompositionTime: time.Duration(0), + Time: recorder.prevDuration, + Data: avccBytes, + }) + if err != nil { + return err + } + + return nil +} + +func (recorder *Mp4Recorder) Close() error { + if !recorder.initialized { + log.Printf("warn: Mp4Recorder was never initialized") + return nil + } + + log.Printf("Mp4Recorder: closing") + if err := recorder.muxer.WriteTrailer(); err != nil { + return err + } + + return recorder.muxer.Close() +} diff --git a/zoom/streams.go b/zoom/streams.go index c8f2cea..bedabfc 100644 --- a/zoom/streams.go +++ b/zoom/streams.go @@ -3,15 +3,14 @@ package zoom import ( "encoding/hex" "errors" - "io" "log" - "os" "time" "net/http" "net/url" "github.com/RealKeyboardWarrior/zoomer/zoom/codecs/opus" + "github.com/RealKeyboardWarrior/zoomer/zoom/formats/mp4" "github.com/RealKeyboardWarrior/zoomer/zoom/rtp" "github.com/RealKeyboardWarrior/zoomer/zoom/streampkt" "github.com/gorilla/websocket" @@ -162,16 +161,6 @@ func CreateZoomScreenShareStreams(session *ZoomSession) (*ZoomStreams, error) { return final, nil } -func Recorder() (io.WriteCloser, error) { - f, err := os.Create(time.Now().Format("2006-01-02-15-04-05") + ".h264") - if err != nil { - return nil, err - } - return f, nil - // defer f.Close() - // n2, err := f.Write(d2) -} - func createWebsocket(name string, websocketUrl string) (*websocket.Conn, error) { log.Printf("CreateZoomStreams: dialing url= %v", websocketUrl) dialer := websocket.Dialer{ @@ -204,11 +193,18 @@ func (streams *ZoomStreams) StartReceiveChannel() { } connection.SetCloseHandler(closeHandler) - recorder, err := Recorder() + videoRecorder, err := mp4.NewRecorder() if err != nil { log.Fatal(err) } - defer recorder.Close() + go (func() { + time.Sleep(60 * time.Second) + err := videoRecorder.Close() + if err != nil { + panic(err) + } + })() + //defer videoRecorder.Close() audioRecorder, err := opus.CreateNewPCMRecorder() if err != nil { @@ -270,7 +266,7 @@ func (streams *ZoomStreams) StartReceiveChannel() { return } if sample != nil { - _, err = recorder.Write(sample.Data) + err = videoRecorder.WritePacket(sample.Data, sample.Duration) if err != nil { log.Fatal(err) return From c45b6d4d251452549c9f152b305a1056eddf0a1a Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:26:35 +0200 Subject: [PATCH 3/8] fix: incorrect PT in log --- zoom/rtp/ext/rtp_metadata_screenshare.go | 2 +- zoom/rtp/ext/rtp_metadata_video.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/zoom/rtp/ext/rtp_metadata_screenshare.go b/zoom/rtp/ext/rtp_metadata_screenshare.go index df71bce..469caff 100644 --- a/zoom/rtp/ext/rtp_metadata_screenshare.go +++ b/zoom/rtp/ext/rtp_metadata_screenshare.go @@ -45,7 +45,7 @@ func DecodeScreenShareMetadata(rtpPacket *rtp.Packet) (*RtpMetadata, error) { log.Printf("rtp extensions [RtpId id=%v] [meta=%v] [%v]", id, svcMeta, resolutionMeta) if rtpPacket.PayloadType == 110 { - log.Printf("rtp [PT type=10] payload=%v", hex.EncodeToString(rtpPacket.Payload)) + log.Printf("rtp [PT type=%v] payload=%v", rtpPacket.PayloadType, hex.EncodeToString(rtpPacket.Payload)) return nil, nil } else if rtpPacket.PayloadType == 99 { // Expected payload format diff --git a/zoom/rtp/ext/rtp_metadata_video.go b/zoom/rtp/ext/rtp_metadata_video.go index f6f45be..5b03bd1 100644 --- a/zoom/rtp/ext/rtp_metadata_video.go +++ b/zoom/rtp/ext/rtp_metadata_video.go @@ -19,7 +19,7 @@ func DecodeVideoMetadata(rtpPacket *rtp.Packet) (*RtpMetadata, error) { } } if rtpPacket.PayloadType == 110 { - log.Printf("rtp [PT type=10] payload=%v", hex.EncodeToString(rtpPacket.Payload)) + log.Printf("rtp [PT type=%v] payload=%v", rtpPacket.PayloadType, hex.EncodeToString(rtpPacket.Payload)) return nil, nil } else if rtpPacket.PayloadType == 98 { // Expected payload format From d99adb78b0960d7017c96ddf5943f68ce8022ade Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:26:54 +0200 Subject: [PATCH 4/8] nit: add some info to video quality --- examples/record-video/videorecoder.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/record-video/videorecoder.go b/examples/record-video/videorecoder.go index bf78b0d..cab4d09 100644 --- a/examples/record-video/videorecoder.go +++ b/examples/record-video/videorecoder.go @@ -73,7 +73,7 @@ func main() { if person.BVideoOn { // Start listening to their video feed // {"evt":12303,"body":{"subInfoList":[{"id":16778240,"size":2,"bOn":false}]},"seq":18} - session.VideoSubscribeRequest(person.ID, 4) + session.VideoSubscribeRequest(person.ID, 4) // HQ: 4, MED: 3 } else { // Stop listening to their video feed // {"evt":12305,"body":{"subIDList":[{"id":16778240}]},"seq":17} From c4fcbf56995a9468350fcc8c68ac3a4faeb8540e Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:27:16 +0200 Subject: [PATCH 5/8] chore: add deps & improve gitignore --- .gitignore | 3 +++ go.mod | 1 + go.sum | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/.gitignore b/.gitignore index 784578e..d2bfd94 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ .env **/*.log **/*.h264 +**/*.h264log +**/*.mp4 +**/*.fmp4 **/*.ogg **/*.raw **/*.exe diff --git a/go.mod b/go.mod index 2e34a26..d7913a5 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/RealKeyboardWarrior/zoomer go 1.14 require ( + github.com/RealKeyboardWarrior/joy4 v1.0.31 // indirect github.com/google/uuid v1.3.0 github.com/gorilla/websocket v1.4.2 github.com/joho/godotenv v1.4.0 diff --git a/go.sum b/go.sum index c1ee39c..4a2e9b2 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,9 @@ +github.com/RealKeyboardWarrior/joy4 v1.0.29 h1:rLocLhfPdP2sdgXYf/5WlCgXcJYKDQZzUv06FSudWoE= +github.com/RealKeyboardWarrior/joy4 v1.0.29/go.mod h1:nEH4UPkq2g3twTHS4l5YmmYanYzi53N31S+87pEqmdk= +github.com/RealKeyboardWarrior/joy4 v1.0.30 h1:CNlyC9uUmyGmwIfmw49t2lr8/k1wTCpbJ6tXM0ghvPo= +github.com/RealKeyboardWarrior/joy4 v1.0.30/go.mod h1:kMdgn+vjjtfOOMTs/i1s8DHqGw5jKrMJqbGsAdZTOII= +github.com/RealKeyboardWarrior/joy4 v1.0.31 h1:IggOsIKN5XkjOARfDk/ERabVnz3mPEtZ0cyzi2JFges= +github.com/RealKeyboardWarrior/joy4 v1.0.31/go.mod h1:kMdgn+vjjtfOOMTs/i1s8DHqGw5jKrMJqbGsAdZTOII= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= From f4270d8189cdf781d641308475df40ed0c4e632a Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:27:38 +0200 Subject: [PATCH 6/8] fix: explicitly skip decoding PT 110 --- zoom/rtp/rtp_decoder.go | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/zoom/rtp/rtp_decoder.go b/zoom/rtp/rtp_decoder.go index 336e822..6060a7c 100644 --- a/zoom/rtp/rtp_decoder.go +++ b/zoom/rtp/rtp_decoder.go @@ -74,18 +74,18 @@ func (parser *ZoomRtpDecoder) getSampleBuilderFor(ssrc uint32) (*samplebuilder.S } // TODO: think about reasonable max late - maxLate := uint16(400) - // TODO: add audio support + maxLate := uint16(400) // Amount of RTP packets that can be in the queue + var sampleRate uint32 var depacketizer rtp.Depacketizer switch parser.streamType { case STREAM_TYPE_SCREENSHARE, STREAM_TYPE_VIDEO: depacketizer = h264.NewVideoDepacketizer(decryptor) + sampleRate = uint32(90000) case STREAM_TYPE_AUDIO: depacketizer = opus.NewAudioDepacketizer(decryptor) + sampleRate = uint32(16000) } - // TODO: fix sample rate - sampleRate := uint32(1) parser.sampleBuilders[ssrc] = samplebuilder.New(maxLate, depacketizer, sampleRate) } return parser.sampleBuilders[ssrc], nil @@ -100,6 +100,7 @@ func (parser *ZoomRtpDecoder) Decode(rawPkt []byte) (*media.Sample, error) { return nil, err } + log.Printf("rtp: active decoder %v", parser.streamType) log.Printf("rtp header [M = %v] [PT type=%v] [SN seq=%v] [TS timestamp=%v] [P padding=%v size=%v] [ssrc=%v csrc=%v]", rtpPacket.Marker, rtpPacket.PayloadType, rtpPacket.SequenceNumber, rtpPacket.Timestamp, rtpPacket.Padding, rtpPacket.PaddingSize, rtpPacket.SSRC, rtpPacket.CSRC) log.Printf("rtp payload [PYLD size=%v data=%v]", len(rtpPacket.Payload), hex.EncodeToString(rtpPacket.Payload)) @@ -143,7 +144,19 @@ func (parser *ZoomRtpDecoder) Decode(rawPkt []byte) (*media.Sample, error) { // 4. Push the RTP packet to the sampleBuilder, this re-orders the packets based // on the RTP Sequence, they may arrive out of order aggregates them and calls // the correct depacketizer (VideoDepacketizer / AudioDepacketizer). - sampleBuilder.Push(rtpPacket) + switch parser.streamType { + case STREAM_TYPE_VIDEO: + if rtpPacket.PayloadType == 98 { + sampleBuilder.Push(rtpPacket) + } else { + log.Printf("ZoomRtpDecoder: skipping writing RTP packet to SampleBuilder because wrong PT") + return nil, nil + } + case STREAM_TYPE_SCREENSHARE: + fallthrough + case STREAM_TYPE_AUDIO: + sampleBuilder.Push(rtpPacket) + } // 5. Pop a sample, may return nil if no packets are ready yet. sample := sampleBuilder.Pop() @@ -151,5 +164,9 @@ func (parser *ZoomRtpDecoder) Decode(rawPkt []byte) (*media.Sample, error) { // THIS IS BECAUSE THE SAMPLE BUILDER ALWAYS LAGS BEHIND ONE PACKET AND MAY // AGGREGATE PACKETS IN THE CASE OF VIDEO STREAMS. + if sample != nil && sample.PrevDroppedPackets > 0 { + log.Printf("ZoomRtpDecoder: dropped %v packets", sample.PrevDroppedPackets) + } + return sample, nil } From 77dc3ddf7e1fdf2cec6fa26fc89188fcb44263ef Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:27:59 +0200 Subject: [PATCH 7/8] chore: start experimenting for PT 110 --- zoom/rtp/rtp_test.go | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 zoom/rtp/rtp_test.go diff --git a/zoom/rtp/rtp_test.go b/zoom/rtp/rtp_test.go new file mode 100644 index 0000000..c605b74 --- /dev/null +++ b/zoom/rtp/rtp_test.go @@ -0,0 +1,43 @@ +package rtp + +import ( + "encoding/hex" + "log" + "testing" + + "github.com/pion/rtp" +) + +func TestRtpPacketPayloadType110(t *testing.T) { + + rawPkts := []string{ + "00b2260501039e90d9b2659bed2e2c01000402bede0004124000003560be396c396c50007000001c865adb6e92bd7f53c1335880949ab1717da719828bcc344b97f830fd42650d07ee2479c8da9e3bf5e46c7fb411b1d496d8abedab7bbabc874d2fb749b0226000245ee3f7591617ac251bf85ed9d4120693a686461b84a7c0665f7ff65baf90802fb44cab5ee022bcd7986f2f52d1f5777d7e6333c58ae900db76ce489628d832c95e6b8846d4da92673dfef61177e07903efea2a980c26957e1d1a0f062dc581a42631c521438af44a0a0b0bd92c7ed8cabf42d6a217aa85280893e14097877b013f2a158929167679c2fd3f57b685860260ab08a32006bce7eb31b2035b59cc7b4fb9e803320fd0bfb261ddb8819c7ddd338129fb695a73be02bb9a544633e14ca0b9d873af5ead211d59274db6dccddde0a09168a20606e7cfa146f3d1c030d6b0ca46c1bd9cd887484106cc9025d5a0ba21bd6ea951c70724c7a09c058234f5863e81e93550c420d76998c9b5c28b80e8f082f0b6da4c5fc3df3686efb0961efd40677861c09a1f8999d830c4a0fe3f121b7d660899e87c3de1138733066ccda5442f9193623779a3214e6b94beb2e986eaa04d32994ed45a4747df58ccdda4df4426786fdabedaa3f1ed7a7a34941d98e9619a467afd04393207d8d13d002b0b00d9d5f71085cf5ba7d991370ea220158369fe29f2a195b1518f0c0c0fdb406d69b42d6bfae172d78696b3a848b7dd4e8e6a512f759c6db8adb977aead0e563bb2724e95ef07aa6a56e2a6e802017c8c11fe06e40de8b7f4e34f8e9026798f053c74880c5c9c29a3b1201d2455d4abe5b11054f3a3d4b2892f16bbb0f1da1f189cec74d79a8efb5018b2bbca806481e9d887353bbba063829997e8d5929d0f21c60be784dcdbafa9de81bec67ea4fa199f68cdc060c50bce3e74cf290d0258ed485df7d3c6d4f2b95c99a4f047c9ecbffd0204c4f58ad4c68d1e77826bb77c64a8b6de99f03b035b1c60c8960f9b65837b574374e93f7c18ec30f4da0fe451b31c5afc52dbde18b940dc45e253b860a45a3d45393116c3407880c6b308cedf0ba3740c253ac0e681f671d1c174248a794705b2cba2ad645db974815ded40891dac18e93884ec1db20d7ea072cb6aca9c02ed89cbcf2dda9afd239e40edd60e9d0748d87a19171f98c6055c20ccc49d3a49e2fbe558ba132cb8cee88189c045dfb6dd0c204a1866dc0dcd48fafb695dc14115b15e929bc0a42dfc2e4f379630cf3e6613b0e4932176314b925e5dbeb684597a6ea84190ab6de556b1", + "00b22d0501011a90d9b2079bed4b5a01000402bede0004124000003560963976396c50007000001c8666e6c75b98a3f69020981a797963df9c4802c88b923f1cf6abc0291b8341182cb142a3aebef0c997d46277d9ae4614a5789a941b55b71655823bd017d732f63ccb3507e078fdae0014feaa2f5123a96cf8d2cbf0513a0deeac84ca2c2ba67a73c39da0b6ae1d61647e4fb1df4f9da0c07dd31e392579dcf8ad8d3f080a2d9987e651204f543bbbfd2aa3bf9d758300c07dfb6ff387a6be0f4049946645d23731e4a8af6630fe959d77281059433f3bdc7519cf6ce9638b5a103961f356998ed3f1f1141e84efcdc75a54ccfc508afa6d93ef09739b398701e7318e3bbd84cf2fe8c32680bb7f02489afa1577a8f0209aca3de63ea22f6ecfbc1005722feb5a93dd092fd889f5ce72803616acc0c2e96b4ac5cb245f66cd251500af46f98297376a2ab56406a415cb42f0de38bf6cbdb561f49a8412c4ab2772c38baea14f3bc423f0d5f92889f14126c3df178e42916ced46a906688bee303cce89144b86c6c0066c3f8d692c13c90a7537b010dc7c77f3f26afc6248ae854c0e16e24c47ef4d426733f482c9b3eb2e40a2250ebcfa5947c0a5378a7654f05c90bf35525f2aaef9a85a86ce844a03f9e7801f406a9a0d85f71a35e50d94d7c75ba70072409b325a89e8d98e80", + "00b244030101aa9045b2409bee536001000402bede00041240000035e25e39d039c650007000001c4e83a0a32dff3e73b204e8e27bfc3b5c3665978e942d9ba684ecc79aa491608f2ef004198c2a140355975e2769f718ccffd66535e72c92daa89a3d5891389da0bfb3671f157bb4a4ba0bde599128fb371b06eca7dc651e36ac8303f0c57bed79fa69ad3e378cc4067c8ff77f3af1a3787fa1edfaad82f7bd7a59b90e33dcee8526ae2c5311f1299dde6b044c6597a82f6209df3f8ed8bb9370fbcd2ea46c785f1b9e204b2025e579227f4c5a5a72282c6cfafbc5fecd194b52e2bd6f05e213c951abdaa7dbb15430e5adc9aed8f6aee01d467ec54a2e36075c79511601f422997dfc19ecde7ef26eef3736aa6b10e8088311628363675888672aa1d0e97ba49cf68e7bf06ebf673eb96a9c3ce5f624aeabd99ed608fb0357238335a4e5d74aeb79e8fa0228c4fdee6ddd56dd4eb7ab9c9da05f4ddfaaca3f0d531ab3e557b12b6ad8522474b0c747f0b9e367dbeadad2b2e32aaa1838e1facf5c0df6bb7e2f9f7a510829dd13a2", + "00b25d0401012c9031b2969befb2f001000402bede0004124000003525b23a3e3a3450007000001ca250bc03eaf6b9c8954ae93c9fc397dbe020e22abcda2a2a8c6f48fe7927f009ddbc3abcdb91688ff3caee922cb2813a0f74c913f2493e5577998f19b92ef6ee68b86c82bd8c797b7bc13dc0bc854962a73310243adbdd4257c7fbda836d5a07e86e3798fc78661b6fdebcac9a59da308153db43d914da5e89a938b1c17375bc42d9776a4f17f545b766538ff9629d28488fcac340ca388a5f52b7206a9ac7fba842d4b7887108bc043c027c3d6f7dfee46406b07dda6bceb9d76a430e6733eaaad8de4848de0b712f89f70cced5f67da41f98853724ae7bb1ba142cc755b0e3e513c45add04d834fa45ff359e3d19fae800a2772ee6a229db9adfb8d80843257ff71ec712e538f9fd8cbf6d36c62dee1e221f451692883f09686bdbf3fc4177edc616e9200508618cc45377278639015874d2e5617ec3d1d8f00aaedd978e1247e687a5eaefdacad59302ac67f485e2f5ffff61696355073597206975f04d5d71ff4676d095a2a9bf50b3e39b69d91897d9160c06032b55d807d3065c963e28e85cbb5e403bd8c486ab851f7685155eeefec68ca7", + "00b276030101bc9045b25a9bf100ec01000402bede00041240000035e25e3aac3aa250007000001c4e63e7b7db84cb55b1cd17b695a2fb060f96f34ab0d0d8f3016f5ce133fa70cc16c63b5eadfae39d254aa037cd1c50eecfbe29ffc38cb9ae327a06a13c65751ced2f2b033f292782f2e1f7b6f72c3b5ca74f64cef085ddf484af07d0770c3815cfeef7ea8b1471193abab365ffcfe02255206b62feb8d35a6a8a43233843e808210d000475aedb18dc24797dee7c46aab22be2e74acab4f4e5ddd6a96850cf0d16adb847dfbb7800cfbf3f24b86e829eb2c7e7b14c4cbe492a5a1d6b20718615fe296fdc2afec0c3fb5ed8267c3265cd735d83aa20ba7a6d38383f7e3a00f44483db795cc55b87a3204d27d458fa54f2086cb26f244ff2ba5753cb7aa34f75655a4286cda5b60eea449ace3001c03ffedded40998fdcdbd0424ee4b6c276eb75fe11365575b43cb03bdc41cdbbd2d9720f80115310676ef2589b7aa3126ce63736b9e4bfdde80df06f0beaa22a1959b1e409f11bf80fa5ad2cb1c291b0ab138a614fe8d1aa7fc41aa25f458864e7318e08f4639c537f6ac225f0a70ebfa465e8e32dfb80b07d80cbd7295a15a1b7f6a12aae73f0ac", + "00b2900301018f9045b2949bf2721001000402bede00041240000035e25e3b243b1a50007000001c4e13e858957903fd1b5e5a9786cfdf998266cdbc1a13dc2902fae6cac4493a6e977868212ccdb1c2813a3179340618e00fb0c53f16fe8f4f04fdd6afde8d21a133795f00d6620fce7a341f932f91efdbc053f230d41d92807ee16295eda21e195bc3e64093f3ed91d9bdfb3c11bb3ab2d4a6c3f34ce2fec7313e9c79056feaaec67fdc39ab117f02fffcee1c17e7c1b5809efcd24d946b8b988b651e03fb8652f4cf9e8e71fde36bbd1f2819c280baad56f9e62746643524a74034c66fab8ba6397a750f418f69175ad582eeb8752bebde5fa9532c554061ae6df2e5799bc6b71323ca98fd842300753615b3d1c79fba090d2efbd504a00dd15f876e63b2f1769566ba0ba313dc6d209d17db3e88467e08aa1d6108ff54376616b178b3753f504e5efe79673d09bd850c5abaa641346c3207a6b4a45971cf054120a61e6bc8bf82b1722afb993679065608399f206927cc011ea5eba0d35fe9c24e86282712cb", + "00b2a8040101ad9031b28a9bf3bfb201000402bede0004124000003525b23b923b8850007000001ca250996d38094f7950594786c781c4b1242e3bec806384df6860c5c45b241bb04c799dbd68122515c14da485364a40c033d6635e9eb6f056eebbf92ccb2ac0beaa85e190d5a274499bd7023a83e5443852afe0ac9bef8a002f9ea0ede87b00439b98e0fb52917d3e50a44788bfa8abdc28a71898481cb3296a4803bf913b79840f765b154f0bd407ab0d78d8cce0c2156a737eb2b8682f84e080d0caf742d33ecdb349c55e566bdf116049ffaa487d8903ff76ed7098c32610d075a4091ff2647a81fd0c2787033254de171e682f0007ba592eb594295807a30a7f9429d4f81af9a7c1a9e8a8618b35cd7b236a3636958770303240e943b788470f9cd8ec51c798f3cbae45be9ee1e20ffa78247a498107f0774d4e2d79f3e04e4e247e5274f4fadaec8e1a90304fd4bca5a2f66fcef87d524edf2d5d5325f874006873357d1965fd89f5ac327e0ef1f915aa84cd953895e8b88021b4cb28f37a669ba3c445f831c823b59e56bbd32527f1fbff27e581c3dbd6a49ce390815681", + // Different logs: + "0043890501018e90d94321d9d1928601000402bede0004124ff0003560bc1d171d1750007000001c86626016058f369134035bb21d6a14e06557061af34a3809a4ef1c2717a369537bc7681f584642320f6be686a705b03fa76e00aa52f7dd4869b378c5f0fde56b473ded015ce52d280f93c51c7b980e97063dc95acf89f1290468c102ce319ec27ab19b5cfc3f2ec0dbb036bf8b2a1c2049a11a4724c6d5d7387c54419320a34eebe0654632755efb163808a21608b7c817516170e3fdef7b21a605fbba0f4b48f948ebc03c09bae4a469fdbebb87c35aa5a267daa29d1c37bfce83a3dd2911d8e4f6b87ac97d2cf84eea9328b4e7363772b557036363c71c0b82ffdb42eedc9efb9ea76660b65cebcd61afb1cb30c8ad41d0b0e516febd885b09bcf15f03496ec21ec9a7ac2c4f760e9ed22e2f95d334e11aa39fc0d5822f41ccf5602660cb062dc527e66bba05a13eda669737951297ddd4bd9d1e4a32d4fe5d6ff1efaa9288e8a1ae66f88b61d81dc985e946e3c9ae6d4442c6f82801699f7933ea9f8c6c815ab78e7984ff94333d0f3fc4c60bd1d3d069c32ee3514f74284afcaf935b57c20839875d2cdb8b3ce41e3c526db18c8c4122c4cfcffea5ffd792b31cff0060bb3cfa61afc411be184b6644032bbaa9acc65319", + } + + //depakcetizer := h264.NewNaluPacketizer() + + for _, rawPktHex := range rawPkts { + rawPkt, _ := hex.DecodeString(rawPktHex[14:]) + rtpPacket := rtp.Packet{} + err := rtpPacket.Unmarshal(rawPkt) + if err != nil { + t.Error(err) + } + log.Printf("%v", rtpPacket) + + // frame, err := depakcetizer.Unmarshal(rtpPacket.Payload) + // if err != nil { + // t.Error(err) + // } + // log.Printf("frame = %v", hex.EncodeToString(frame)) + } + +} From 64e8e35b79155d7bf6b2529c6ba9c5c138f0dfcb Mon Sep 17 00:00:00 2001 From: KeyboardWarrior Date: Wed, 6 Sep 2023 22:28:15 +0200 Subject: [PATCH 8/8] idk: I change this audio stuff but not sure --- zoom/streampkt/pkt_audio.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zoom/streampkt/pkt_audio.go b/zoom/streampkt/pkt_audio.go index cf56b52..e37c1a8 100644 --- a/zoom/streampkt/pkt_audio.go +++ b/zoom/streampkt/pkt_audio.go @@ -26,8 +26,8 @@ func (pkt *ZoomAudioPkt) Unmarshal(data []byte) error { pkt.lenRtp = rtpPktSize pkt.Rtp = rtpPkt - if len(data) > int(45+rtpPktSize) { - pkt.AdditionalData = data[45+rtpPktSize:] + if len(data) > int(23+rtpPktSize) { + pkt.AdditionalData = data[23+rtpPktSize:] } return nil }