stream-server/rtmp/amf/encode.go

66 lines
2 KiB
Go
Raw Normal View History

2023-08-15 12:32:44 +05:00
package amf
import (
"math"
"encoding/binary"
"errors"
)
2023-08-15 13:16:29 +05:00
func Encode(amf_root_obj AMFObj) ([]byte, error) {
2023-08-15 12:32:44 +05:00
tmp_buffer := make([]byte, 1024)
bytes_encoded := 0
for i := 0; i < len(amf_root_obj); i++ {
if err := encode_next(amf_root_obj[i], &tmp_buffer, &bytes_encoded); err != nil {
2023-08-15 13:16:29 +05:00
return tmp_buffer[:bytes_encoded], err
2023-08-15 12:32:44 +05:00
}
}
2023-08-15 13:16:29 +05:00
return tmp_buffer[:bytes_encoded], nil
2023-08-15 12:32:44 +05:00
}
2023-08-15 14:27:28 +05:00
func encode_marker(marker_val uint8, tmp_buffer *[]byte, bytes_encoded *int) {
(*tmp_buffer)[*bytes_encoded] = marker_val
*bytes_encoded++
}
2023-08-15 12:32:44 +05:00
func encode_number(num_to_enc float64, tmp_buffer *[]byte, bytes_encoded *int) {
2023-08-15 14:27:28 +05:00
binary.BigEndian.PutUint64((*tmp_buffer)[*bytes_encoded:*bytes_encoded + 8], math.Float64bits(num_to_enc))
*bytes_encoded += 8
}
func encode_string(str_to_enc string, tmp_buffer *[]byte, bytes_encoded *int) {
str_len := len(str_to_enc)
binary.BigEndian.PutUint16((*tmp_buffer)[*bytes_encoded:*bytes_encoded + 2], uint16(str_len))
*bytes_encoded += 2
copy((*tmp_buffer)[*bytes_encoded:*bytes_encoded + str_len], str_to_enc)
*bytes_encoded += str_len
}
func encode_object(obj_to_enc AMFObj, tmp_buffer *[]byte, bytes_encoded *int) {
for prop, value := range obj_to_enc {
encode_string(prop.(string), tmp_buffer, bytes_encoded)
encode_next(value, tmp_buffer, bytes_encoded)
}
2023-08-15 12:32:44 +05:00
}
func encode_next(amf_obj interface{}, tmp_buffer *[]byte, bytes_encoded *int) (error) {
switch amf_obj.(type) {
case float64:
2023-08-15 14:27:28 +05:00
encode_marker(0, tmp_buffer, bytes_encoded)
2023-08-15 12:32:44 +05:00
encode_number(amf_obj.(float64), tmp_buffer, bytes_encoded)
2023-08-15 14:27:28 +05:00
case string:
encode_marker(2, tmp_buffer, bytes_encoded)
encode_string(amf_obj.(string), tmp_buffer, bytes_encoded)
case AMFObj:
encode_marker(3, tmp_buffer, bytes_encoded)
encode_object(amf_obj.(AMFObj), tmp_buffer, bytes_encoded)
encode_string("", tmp_buffer, bytes_encoded)
encode_marker(9, tmp_buffer, bytes_encoded)
case nil:
encode_marker(5, tmp_buffer, bytes_encoded)
2023-08-15 12:32:44 +05:00
default:
return errors.New("Type not implemented")
}
return nil
}