Beispiel #1
0
func (v *AgentManager) NewRtmpPublishAgent(conn *protocol.RtmpConnection, wc core.WorkerContainer) (core.Agent, error) {
	v.lock.Lock()
	defer v.lock.Unlock()

	// finger the source agent out, which dup to other agent.
	var ok bool
	var dup core.Agent
	if dup, ok = v.sources[conn.Req.Uri()]; !ok {
		dup = NewDupAgent()
		v.sources[conn.Req.Uri()] = dup

		if err := dup.Open(); err != nil {
			core.Error.Println("open dup agent failed. err is", err)
			return nil, err
		}

		// start async work for dup worker.
		wait := make(chan bool, 1)
		core.Recover("", func() (err error) {
			wait <- true

			if err = dup.Work(); err != nil {
				core.Error.Println("dup agent work failed. err is", err)
				return
			}
			return
		})
		<-wait
	}

	// when dup source not nil, then the source is using.
	if dup.Source().GetSink() != nil {
		err := AgentBusyError
		core.Error.Println("source busy. err is", err)
		return nil, err
	}

	// create the publish agent
	r := &RtmpPublishAgent{
		conn: conn,
		wc:   wc,
	}

	// tie the publish agent to dup source.
	if err := dup.Source().Tie(r.Sink()); err != nil {
		core.Error.Println("tie agent publish sink to dup source failed. err is", err)
		return nil, err
	}

	return r, nil
}