Files
go-rtmp/message/body_decoder.go
T
2018-09-29 17:43:01 +09:00

343 lines
9.2 KiB
Go

//
// Copyright (c) 2018- yutopp (yutopp@gmail.com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt)
//
package message
import (
"bytes"
"github.com/pkg/errors"
"io"
)
type BodyDecoderFunc func(r io.Reader, e AMFDecoder, v *AMFConvertible) error
var DataBodyDecoders = map[string]BodyDecoderFunc{
"@setDataFrame": DecodeBodyAtSetDataFrame,
}
func DataBodyDecoderFor(name string) BodyDecoderFunc {
dec, ok := DataBodyDecoders[name]
if ok {
return dec
}
return func(_ io.Reader, d AMFDecoder, _ *AMFConvertible) error {
objs := make([]interface{}, 0)
for {
var tmp interface{}
if err := d.Decode(&tmp); err != nil {
break
}
objs = append(objs, tmp)
}
return &UnknownDataBodyDecodeError{
Name: name,
Objs: objs,
}
}
}
func DecodeBodyAtSetDataFrame(r io.Reader, _ AMFDecoder, v *AMFConvertible) error {
buf := new(bytes.Buffer)
if _, err := io.Copy(buf, r); err != nil {
return errors.Wrap(err, "Failed to decode '@setDataFrame' args[0]")
}
var cmd NetStreamSetDataFrame
if err := cmd.FromArgs(buf.Bytes()); err != nil {
return errors.Wrap(err, "Failed to reconstruct '@setDataFrame'")
}
*v = &cmd
return nil
}
var CmdBodyDecoders = map[string]BodyDecoderFunc{
"connect": DecodeBodyConnect,
"createStream": DecodeBodyCreateStream,
"deleteStream": DecodeBodyDeleteStream,
"publish": DecodeBodyPublish,
"play": DecodeBodyPlay,
"releaseStream": DecodeBodyReleaseStream,
"FCPublish": DecodeBodyFCPublish,
"FCUnpublish": DecodeBodyFCUnpublish,
"getStreamLength": DecodeBodyGetStreamLength,
"ping": DecodeBodyPing,
"closeStream": DecodeBodyCloseStream,
}
func CmdBodyDecoderFor(name string, transactionID int64) BodyDecoderFunc {
dec, ok := CmdBodyDecoders[name]
if ok {
return dec
}
// TODO: support result
return func(_ io.Reader, d AMFDecoder, _ *AMFConvertible) error {
objs := make([]interface{}, 0)
for {
var tmp interface{}
if err := d.Decode(&tmp); err != nil {
break
}
objs = append(objs, tmp)
}
return &UnknownCommandBodyDecodeError{
Name: name,
TransactionID: transactionID,
Objs: objs,
}
}
}
func DecodeBodyConnect(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var object map[string]interface{}
if err := d.Decode(&object); err != nil {
return errors.Wrap(err, "Failed to decode 'connect' args[0]")
}
var cmd NetConnectionConnect
if err := cmd.FromArgs(object); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'connect'")
}
*v = &cmd
return nil
}
func DecodeBodyConnectResult(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var properties interface{}
if err := d.Decode(&properties); err != nil {
return errors.Wrap(err, "Failed to decode 'connect.result' args[0]")
}
var information interface{}
if err := d.Decode(&information); err != nil {
return errors.Wrap(err, "Failed to decode 'connect.result' args[1]")
}
var result NetConnectionConnectResult
if err := result.FromArgs(properties, information); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'connect.result'")
}
*v = &result
return nil
}
func DecodeBodyCreateStream(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var object interface{}
if err := d.Decode(&object); err != nil {
return errors.Wrap(err, "Failed to decode 'createStream' args[0]")
}
var cmd NetConnectionCreateStream
if err := cmd.FromArgs(object); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'createStream'")
}
*v = &cmd
return nil
}
func DecodeBodyCreateStreamResult(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'createStream.result' args[0]")
}
var streamID uint32
if err := d.Decode(&streamID); err != nil {
return errors.Wrap(err, "Failed to decode 'createStream.result' args[1]")
}
var data NetConnectionCreateStreamResult
if err := data.FromArgs(commandObject, streamID); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'createStream.result'")
}
*v = &data
return nil
}
func DecodeBodyDeleteStream(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'deleteStream' args[0]")
}
var streamID uint32
if err := d.Decode(&streamID); err != nil {
return errors.Wrap(err, "Failed to decode 'deleteStream' args[1]")
}
var data NetStreamDeleteStream
if err := data.FromArgs(commandObject, streamID); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'deleteStream'")
}
*v = &data
return nil
}
func DecodeBodyPublish(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{}
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'publish' args[0]")
}
var publishingName string
if err := d.Decode(&publishingName); err != nil {
return errors.Wrap(err, "Failed to decode 'publish' args[1]")
}
var publishingType string
if err := d.Decode(&publishingType); err != nil {
return errors.Wrap(err, "Failed to decode 'publish' args[2]")
}
var cmd NetStreamPublish
if err := cmd.FromArgs(commandObject, publishingName, publishingType); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'publish'")
}
*v = &cmd
return nil
}
func DecodeBodyPlay(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{}
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'play' args[0]")
}
var streamName string
if err := d.Decode(&streamName); err != nil {
return errors.Wrap(err, "Failed to decode 'play' args[1]")
}
var start int64
if err := d.Decode(&start); err != nil {
return errors.Wrap(err, "Failed to decode 'play' args[2]")
}
var cmd NetStreamPlay
if err := cmd.FromArgs(commandObject, streamName, start); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'play'")
}
*v = &cmd
return nil
}
func DecodeBodyReleaseStream(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'releaseStream' args[0]")
}
var streamName string
if err := d.Decode(&streamName); err != nil {
return errors.Wrap(err, "Failed to decode 'releaseStream' args[1]")
}
var cmd NetConnectionReleaseStream
if err := cmd.FromArgs(commandObject, streamName); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'releaseStream'")
}
*v = &cmd
return nil
}
func DecodeBodyFCPublish(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'FCPublish' args[0]")
}
var streamName string
if err := d.Decode(&streamName); err != nil {
return errors.Wrap(err, "Failed to decode 'FCPublish' args[1]")
}
var cmd NetStreamFCPublish
if err := cmd.FromArgs(commandObject, streamName); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'FCPublish'")
}
*v = &cmd
return nil
}
func DecodeBodyFCUnpublish(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'FCUnpublish' args[0]")
}
var streamName string
if err := d.Decode(&streamName); err != nil {
return errors.Wrap(err, "Failed to decode 'FCUnpublish' args[1]")
}
var cmd NetStreamFCUnpublish
if err := cmd.FromArgs(commandObject, streamName); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'FCUnpublish'")
}
*v = &cmd
return nil
}
func DecodeBodyGetStreamLength(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'getStreamLength' args[0]")
}
var streamName string
if err := d.Decode(&streamName); err != nil {
return errors.Wrap(err, "Failed to decode 'getStreamLength' args[1]")
}
var cmd NetStreamGetStreamLength
if err := cmd.FromArgs(commandObject, streamName); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'getStreamLength'")
}
*v = &cmd
return nil
}
func DecodeBodyPing(_ io.Reader, d AMFDecoder, v *AMFConvertible) error { // NLE
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'ping' args[0]")
}
var cmd NetStreamPing
if err := cmd.FromArgs(commandObject); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'ping'")
}
*v = &cmd
return nil
}
func DecodeBodyCloseStream(_ io.Reader, d AMFDecoder, v *AMFConvertible) error {
var commandObject interface{} // maybe nil
if err := d.Decode(&commandObject); err != nil {
return errors.Wrap(err, "Failed to decode 'closeStream' args[0]")
}
var cmd NetStreamCloseStream
if err := cmd.FromArgs(commandObject); err != nil {
return errors.Wrap(err, "Failed to reconstruct 'closeStream'")
}
*v = &cmd
return nil
}