amf.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. package util
  2. import (
  3. "fmt"
  4. "io"
  5. "reflect"
  6. )
  7. // Action Message Format -- AMF 0
  8. // Action Message Format -- AMF 3
  9. // http://download.macromedia.com/pub/labs/amf/amf0_spec_121207.pdf
  10. // http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/amf/pdf/amf-file-format-spec.pdf
  11. // AMF Object == AMF Object Type(1 byte) + AMF Object Value
  12. //
  13. // AMF Object Value :
  14. // AMF0_STRING : 2 bytes(datasize,记录string的长度) + data(string)
  15. // AMF0_OBJECT : AMF0_STRING + AMF Object
  16. // AMF0_NULL : 0 byte
  17. // AMF0_NUMBER : 8 bytes
  18. // AMF0_DATE : 10 bytes
  19. // AMF0_BOOLEAN : 1 byte
  20. // AMF0_ECMA_ARRAY : 4 bytes(arraysize,记录数组的长度) + AMF0_OBJECT
  21. // AMF0_STRICT_ARRAY : 4 bytes(arraysize,记录数组的长度) + AMF Object
  22. // 实际测试时,AMF0_ECMA_ARRAY数据如下:
  23. // 8 0 0 0 13 0 8 100 117 114 97 116 105 111 110 0 0 0 0 0 0 0 0 0 0 5 119 105 100 116 104 0 64 158 0 0 0 0 0 0 0 6 104 101 105 103 104 116 0 64 144 224 0 0 0 0 0
  24. // 8 0 0 0 13 | { 0 8 100 117 114 97 116 105 111 110 --- 0 0 0 0 0 0 0 0 0 } | { 0 5 119 105 100 116 104 --- 0 64 158 0 0 0 0 0 0 } | { 0 6 104 101 105 103 104 116 --- 0 64 144 224 0 0 0 0 0 } |...
  25. // 13 | {AMF0_STRING --- AMF0_NUMBER} | {AMF0_STRING --- AMF0_NUMBER} | {AMF0_STRING --- AMF0_NUMBER} | ...
  26. // 13 | {AMF0_OBJECT} | {AMF0_OBJECT} | {AMF0_OBJECT} | ...
  27. // 13 | {duration --- 0} | {width --- 1920} | {height --- 1080} | ...
  28. const (
  29. AMF0_NUMBER = iota // 浮点数
  30. AMF0_BOOLEAN
  31. AMF0_STRING
  32. AMF0_OBJECT
  33. AMF0_MOVIECLIP
  34. AMF0_NULL
  35. AMF0_UNDEFINED
  36. AMF0_REFERENCE
  37. AMF0_ECMA_ARRAY
  38. AMF0_END_OBJECT
  39. AMF0_STRICT_ARRAY
  40. AMF0_DATE
  41. AMF0_LONG_STRING
  42. AMF0_UNSUPPORTED
  43. AMF0_RECORDSET
  44. AMF0_XML_DOCUMENT
  45. AMF0_TYPED_OBJECT
  46. AMF0_AVMPLUS_OBJECT
  47. )
  48. var (
  49. END_OBJ = []byte{0, 0, AMF0_END_OBJECT}
  50. ObjectEnd = &struct{}{}
  51. Undefined = &struct{}{}
  52. )
  53. type IAMF interface {
  54. IBuffer
  55. Unmarshal() (any, error)
  56. Marshal(any) []byte
  57. Marshals(...any) []byte
  58. }
  59. type EcmaArray map[string]any
  60. type AMF struct {
  61. Buffer
  62. }
  63. func ReadAMF[T string | float64 | bool | map[string]any](amf *AMF) (result T) {
  64. value, err := amf.Unmarshal()
  65. if err != nil {
  66. return
  67. }
  68. result, _ = value.(T)
  69. return
  70. }
  71. func (amf *AMF) ReadShortString() (result string) {
  72. return ReadAMF[string](amf)
  73. }
  74. func (amf *AMF) ReadNumber() (result float64) {
  75. return ReadAMF[float64](amf)
  76. }
  77. func (amf *AMF) ReadObject() (result map[string]any) {
  78. return ReadAMF[map[string]any](amf)
  79. }
  80. func (amf *AMF) ReadBool() (result bool) {
  81. return ReadAMF[bool](amf)
  82. }
  83. func (amf *AMF) readKey() (string, error) {
  84. if !amf.CanReadN(2) {
  85. return "", io.ErrUnexpectedEOF
  86. }
  87. l := int(amf.ReadUint16())
  88. if !amf.CanReadN(l) {
  89. return "", io.ErrUnexpectedEOF
  90. }
  91. return string(amf.ReadN(l)), nil
  92. }
  93. func (amf *AMF) readProperty(m map[string]any) (obj any, err error) {
  94. var k string
  95. var v any
  96. if k, err = amf.readKey(); err == nil {
  97. if v, err = amf.Unmarshal(); k == "" && v == ObjectEnd {
  98. obj = m
  99. } else if err == nil {
  100. m[k] = v
  101. }
  102. }
  103. return
  104. }
  105. func (amf *AMF) Unmarshal() (obj any, err error) {
  106. if !amf.CanRead() {
  107. return nil, io.ErrUnexpectedEOF
  108. }
  109. defer func(b Buffer) {
  110. if err != nil {
  111. amf.Buffer = b
  112. }
  113. }(amf.Buffer)
  114. switch t := amf.ReadByte(); t {
  115. case AMF0_NUMBER:
  116. if !amf.CanReadN(8) {
  117. return 0, io.ErrUnexpectedEOF
  118. }
  119. obj = amf.ReadFloat64()
  120. case AMF0_BOOLEAN:
  121. if !amf.CanRead() {
  122. return false, io.ErrUnexpectedEOF
  123. }
  124. obj = amf.ReadByte() == 1
  125. case AMF0_STRING:
  126. obj, err = amf.readKey()
  127. case AMF0_OBJECT:
  128. m := make(map[string]any)
  129. for err == nil && obj == nil {
  130. obj, err = amf.readProperty(m)
  131. }
  132. case AMF0_NULL:
  133. return nil, nil
  134. case AMF0_UNDEFINED:
  135. return Undefined, nil
  136. case AMF0_ECMA_ARRAY:
  137. size := amf.ReadUint32()
  138. m := make(EcmaArray)
  139. for i := uint32(0); i < size && err == nil && obj == nil; i++ {
  140. obj, err = amf.readProperty(m)
  141. }
  142. case AMF0_END_OBJECT:
  143. return ObjectEnd, nil
  144. case AMF0_STRICT_ARRAY:
  145. size := amf.ReadUint32()
  146. var list []any
  147. for i := uint32(0); i < size; i++ {
  148. v, err := amf.Unmarshal()
  149. if err != nil {
  150. return nil, err
  151. }
  152. list = append(list, v)
  153. }
  154. obj = list
  155. case AMF0_DATE:
  156. if !amf.CanReadN(10) {
  157. return 0, io.ErrUnexpectedEOF
  158. }
  159. obj = amf.ReadFloat64()
  160. amf.ReadN(2)
  161. case AMF0_LONG_STRING,
  162. AMF0_XML_DOCUMENT:
  163. if !amf.CanReadN(4) {
  164. return "", io.ErrUnexpectedEOF
  165. }
  166. l := int(amf.ReadUint32())
  167. if !amf.CanReadN(l) {
  168. return "", io.ErrUnexpectedEOF
  169. }
  170. obj = string(amf.ReadN(l))
  171. default:
  172. err = fmt.Errorf("unsupported type:%d", t)
  173. }
  174. return
  175. }
  176. func (amf *AMF) writeProperty(key string, v any) {
  177. amf.WriteUint16(uint16(len(key)))
  178. amf.WriteString(key)
  179. amf.Marshal(v)
  180. }
  181. func MarshalAMFs(v ...any) []byte {
  182. var amf AMF
  183. return amf.Marshals(v...)
  184. }
  185. func (amf *AMF) Marshals(v ...any) []byte {
  186. for _, vv := range v {
  187. amf.Marshal(vv)
  188. }
  189. return amf.Buffer
  190. }
  191. func (amf *AMF) Marshal(v any) []byte {
  192. if v == nil {
  193. amf.WriteByte(AMF0_NULL)
  194. return amf.Buffer
  195. }
  196. switch vv := v.(type) {
  197. case string:
  198. if l := len(vv); l > 0xFFFF {
  199. amf.WriteByte(AMF0_LONG_STRING)
  200. amf.WriteUint32(uint32(l))
  201. } else {
  202. amf.WriteByte(AMF0_STRING)
  203. amf.WriteUint16(uint16(l))
  204. }
  205. amf.WriteString(vv)
  206. case float64, uint, float32, int, int16, int32, int64, uint16, uint32, uint64, uint8, int8:
  207. amf.WriteByte(AMF0_NUMBER)
  208. amf.WriteFloat64(ToFloat64(vv))
  209. case bool:
  210. amf.WriteByte(AMF0_BOOLEAN)
  211. if vv {
  212. amf.WriteByte(1)
  213. } else {
  214. amf.WriteByte(0)
  215. }
  216. case EcmaArray:
  217. if vv == nil {
  218. amf.WriteByte(AMF0_NULL)
  219. return amf.Buffer
  220. }
  221. amf.WriteByte(AMF0_ECMA_ARRAY)
  222. amf.WriteUint32(uint32(len(vv)))
  223. for k, v := range vv {
  224. amf.writeProperty(k, v)
  225. }
  226. amf.Write(END_OBJ)
  227. case map[string]any:
  228. if vv == nil {
  229. amf.WriteByte(AMF0_NULL)
  230. return amf.Buffer
  231. }
  232. amf.WriteByte(AMF0_OBJECT)
  233. for k, v := range vv {
  234. amf.writeProperty(k, v)
  235. }
  236. amf.Write(END_OBJ)
  237. default:
  238. v := reflect.ValueOf(vv)
  239. if !v.IsValid() {
  240. amf.WriteByte(AMF0_NULL)
  241. return amf.Buffer
  242. }
  243. switch v.Kind() {
  244. case reflect.Slice, reflect.Array:
  245. amf.WriteByte(AMF0_STRICT_ARRAY)
  246. size := v.Len()
  247. amf.WriteUint32(uint32(size))
  248. for i := 0; i < size; i++ {
  249. amf.Marshal(v.Index(i).Interface())
  250. }
  251. amf.Write(END_OBJ)
  252. case reflect.Ptr:
  253. vv := reflect.Indirect(v)
  254. if vv.Kind() == reflect.Struct {
  255. amf.WriteByte(AMF0_OBJECT)
  256. for i := 0; i < vv.NumField(); i++ {
  257. amf.writeProperty(vv.Type().Field(i).Name, vv.Field(i).Interface())
  258. }
  259. amf.Write(END_OBJ)
  260. }
  261. default:
  262. panic("amf Marshal faild")
  263. }
  264. }
  265. return amf.Buffer
  266. }