mirror of
https://github.com/encounter/go-rtmp.git
synced 2026-03-30 11:12:49 -07:00
139 lines
3.7 KiB
Go
139 lines
3.7 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 rtmp
|
|
|
|
import (
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/encounter/go-rtmp/internal"
|
|
"github.com/encounter/go-rtmp/message"
|
|
)
|
|
|
|
var _ stateHandler = (*serverDataInactiveHandler)(nil)
|
|
|
|
// serverDataInactiveHandler Handle data messages from a non operated client at server side.
|
|
// transitions:
|
|
// | "publish" -> serverDataPublishHandler
|
|
// | "play" -> serverDataPlayHandler
|
|
// | _ -> self
|
|
type serverDataInactiveHandler struct {
|
|
sh *streamHandler
|
|
}
|
|
|
|
func (h *serverDataInactiveHandler) onMessage(
|
|
chunkStreamID int,
|
|
timestamp uint32,
|
|
msg message.Message,
|
|
) error {
|
|
return internal.ErrPassThroughMsg
|
|
}
|
|
|
|
func (h *serverDataInactiveHandler) onData(
|
|
chunkStreamID int,
|
|
timestamp uint32,
|
|
dataMsg *message.DataMessage,
|
|
body interface{},
|
|
) error {
|
|
return internal.ErrPassThroughMsg
|
|
}
|
|
|
|
func (h *serverDataInactiveHandler) onCommand(
|
|
chunkStreamID int,
|
|
timestamp uint32,
|
|
cmdMsg *message.CommandMessage,
|
|
body interface{},
|
|
) error {
|
|
l := h.sh.Logger()
|
|
|
|
switch cmd := body.(type) {
|
|
case *message.NetStreamPublish:
|
|
l.Infof("Publisher is comming: %#v", cmd)
|
|
|
|
if err := h.sh.stream.userHandler().OnPublish(timestamp, cmd); err != nil {
|
|
// TODO: Support message.NetStreamOnStatusCodePublishBadName
|
|
result := h.newOnStatus(message.NetStreamOnStatusCodePublishFailed, "Publish failed.")
|
|
|
|
l.Infof("Reject a Publish request: Response = %#v, Err = %+v", result, err)
|
|
if err1 := h.sh.stream.NotifyStatus(chunkStreamID, timestamp, result); err1 != nil {
|
|
return errors.Wrapf(err, "Failed to reply response: Err = %+v", err1)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
result := h.newOnStatus(message.NetStreamOnStatusCodePublishStart, "Publish succeeded.")
|
|
if err := h.sh.stream.NotifyStatus(chunkStreamID, timestamp, result); err != nil {
|
|
return err
|
|
}
|
|
l.Infof("Publisher accepted")
|
|
|
|
h.sh.ChangeState(streamStateServerPublish)
|
|
|
|
return nil
|
|
|
|
case *message.NetStreamPlay:
|
|
l.Infof("Player is comming: %#v", cmd)
|
|
|
|
if err := h.sh.stream.userHandler().OnPlay(timestamp, cmd); err != nil {
|
|
result := h.newOnStatus(message.NetStreamOnStatusCodePlayFailed, "Play failed.")
|
|
|
|
l.Infof("Reject a Play request: Response = %#v, Err = %+v", result, err)
|
|
if err1 := h.sh.stream.NotifyStatus(chunkStreamID, timestamp, result); err1 != nil {
|
|
return errors.Wrapf(err, "Failed to reply response: Err = %+v", err1)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
result := h.newOnStatus(message.NetStreamOnStatusCodePlayStart, "Play succeeded.")
|
|
if err := h.sh.stream.NotifyStatus(chunkStreamID, timestamp, result); err != nil {
|
|
return err
|
|
}
|
|
l.Infof("Player accepted")
|
|
|
|
h.sh.ChangeState(streamStateServerPlay)
|
|
|
|
return nil
|
|
|
|
default:
|
|
return internal.ErrPassThroughMsg
|
|
}
|
|
}
|
|
|
|
func (h *serverDataInactiveHandler) onWinAckSize(
|
|
chunkStreamID int,
|
|
timestamp uint32,
|
|
ackMsg *message.WinAckSize,
|
|
) (err error) {
|
|
return nil
|
|
}
|
|
|
|
func (h *serverDataInactiveHandler) newOnStatus(
|
|
code message.NetStreamOnStatusCode,
|
|
description string,
|
|
) *message.NetStreamOnStatus {
|
|
// https://helpx.adobe.com/adobe-media-server/ssaslr/netstream-class.html#netstream_onstatus
|
|
level := message.NetStreamOnStatusLevelStatus
|
|
switch code {
|
|
case message.NetStreamOnStatusCodeConnectFailed:
|
|
fallthrough
|
|
case message.NetStreamOnStatusCodePlayFailed:
|
|
fallthrough
|
|
case message.NetStreamOnStatusCodePublishBadName, message.NetStreamOnStatusCodePublishFailed:
|
|
level = message.NetStreamOnStatusLevelError
|
|
}
|
|
|
|
return &message.NetStreamOnStatus{
|
|
InfoObject: message.NetStreamOnStatusInfoObject{
|
|
Level: level,
|
|
Code: code,
|
|
Description: description,
|
|
},
|
|
}
|
|
}
|