From 74d95d476908ec0d19fee5aa9cbffa4910250ef3 Mon Sep 17 00:00:00 2001 From: Muaz Ahmad Date: Fri, 11 Aug 2023 15:22:25 +0500 Subject: [PATCH] Basic root and number AMF decoding --- rtmp/amf/decode.go | 60 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 53 insertions(+), 7 deletions(-) diff --git a/rtmp/amf/decode.go b/rtmp/amf/decode.go index 68b62b4..b297a34 100644 --- a/rtmp/amf/decode.go +++ b/rtmp/amf/decode.go @@ -1,13 +1,59 @@ package amf +import ( + "errors" + "encoding/binary" + "math" +) + type AMFObj map[interface{}]interface{} func DecodeAMF(data *[]byte) (AMFObj, error) { - obj := make(AMFObj) - test := make(AMFObj) - obj[0] = "connect" - obj[1] = float64(1) - obj[2] = test - test["tcUrl"] = "rtmp://test-domain.nil/Desktop/tmp" - return obj, nil + var byte_idx uint32 + var root_obj_idx uint8 + amf_root_obj := make(AMFObj) + + for { + top_level_obj, err := read_next(data, &byte_idx) + if err != nil { + return amf_root_obj, err + } + amf_root_obj[root_obj_idx] = top_level_obj + root_obj_idx += 1 + } + return amf_root_obj, nil } + +func read_bytes(data *[]byte, byte_idx *uint32, n uint32) ([]byte, error) { + if int(*byte_idx + n) > len(*data) { + return make([]byte, 0), errors.New("Read goes past end") + } + *byte_idx += n + return (*data)[*byte_idx:*byte_idx + n], nil +} + +func read_number(data *[]byte, byte_idx *uint32) (float64, error) { + float_bytes, err := read_bytes(data, byte_idx, 8) + if err != nil { + return 0.0, err + } + return math.Float64frombits(binary.BigEndian.Uint64(float_bytes)), nil +} + +func read_next(data *[]byte, byte_idx *uint32) (interface{}, error) { + data_type, err := read_bytes(data, byte_idx, 1) + if err != nil { + return nil, err + } + switch data_type[0] { + case 0: + next_obj, err := read_number(data, byte_idx) + if err != nil { + return nil, err + } + return next_obj, nil + } + return nil, errors.New("tmp") +} + +