add ServerDemuxer / ServerMuxer
This commit is contained in:
parent
79f3f92350
commit
6f32e25e03
@ -11,22 +11,6 @@ import (
|
|||||||
|
|
||||||
var Debug bool
|
var Debug bool
|
||||||
|
|
||||||
func Open(filename string) (demuxer av.DemuxCloser, err error) {
|
|
||||||
if demuxer, err = avutil.Open(filename); err != nil {
|
|
||||||
err = fmt.Errorf("avconv: open input `%s` failed: %s", filename, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func Create(filename string) (muxer av.MuxCloser, err error) {
|
|
||||||
if muxer, err = avutil.Create(filename); err != nil {
|
|
||||||
err = fmt.Errorf("avconv: create output `%s` failed: %s", filename, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
Transcode bool
|
Transcode bool
|
||||||
Args []string
|
Args []string
|
||||||
@ -178,12 +162,12 @@ func ConvertCmdline(args []string) (err error) {
|
|||||||
var demuxer av.DemuxCloser
|
var demuxer av.DemuxCloser
|
||||||
var muxer av.MuxCloser
|
var muxer av.MuxCloser
|
||||||
|
|
||||||
if demuxer, err = Open(input); err != nil {
|
if demuxer, err = avutil.Open(input); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer demuxer.Close()
|
defer demuxer.Close()
|
||||||
|
|
||||||
if muxer, err = Create(output); err != nil {
|
if muxer, err = avutil.Create(output); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer muxer.Close()
|
defer muxer.Close()
|
||||||
|
@ -2,6 +2,7 @@ package avutil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
"fmt"
|
"fmt"
|
||||||
"bytes"
|
"bytes"
|
||||||
"github.com/nareix/joy4/av"
|
"github.com/nareix/joy4/av"
|
||||||
@ -52,6 +53,8 @@ type RegisterHandler struct {
|
|||||||
Probe func([]byte)bool
|
Probe func([]byte)bool
|
||||||
AudioEncoder func(av.CodecType)(av.AudioEncoder,error)
|
AudioEncoder func(av.CodecType)(av.AudioEncoder,error)
|
||||||
AudioDecoder func(av.AudioCodecData)(av.AudioDecoder,error)
|
AudioDecoder func(av.AudioCodecData)(av.AudioDecoder,error)
|
||||||
|
ServerDemuxer func(string)(bool,av.DemuxCloser,error)
|
||||||
|
ServerMuxer func(string)(bool,av.MuxCloser,error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
@ -111,11 +114,26 @@ func (self *Handlers) NewAudioDecoder(codec av.AudioCodecData) (dec av.AudioDeco
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Handlers) Open(uri string) (demuxer av.DemuxCloser, err error) {
|
func (self *Handlers) Open(uri string) (demuxer av.DemuxCloser, err error) {
|
||||||
|
listen := false
|
||||||
|
if strings.HasPrefix(uri, "listen:") {
|
||||||
|
uri = uri[len("listen:"):]
|
||||||
|
listen = true
|
||||||
|
}
|
||||||
|
|
||||||
for _, handler := range self.handlers {
|
for _, handler := range self.handlers {
|
||||||
if handler.UrlDemuxer != nil {
|
if listen {
|
||||||
var ok bool
|
if handler.ServerDemuxer != nil {
|
||||||
if ok, demuxer, err = handler.UrlDemuxer(uri); ok {
|
var ok bool
|
||||||
return
|
if ok, demuxer, err = handler.ServerDemuxer(uri); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if handler.UrlDemuxer != nil {
|
||||||
|
var ok bool
|
||||||
|
if ok, demuxer, err = handler.UrlDemuxer(uri); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,6 +188,23 @@ func (self *Handlers) Open(uri string) (demuxer av.DemuxCloser, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Handlers) Create(uri string) (muxer av.MuxCloser, err error) {
|
func (self *Handlers) Create(uri string) (muxer av.MuxCloser, err error) {
|
||||||
|
listen := false
|
||||||
|
if strings.HasPrefix(uri, "listen:") {
|
||||||
|
uri = uri[len("listen:"):]
|
||||||
|
listen = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, handler := range self.handlers {
|
||||||
|
if listen {
|
||||||
|
if handler.ServerMuxer != nil {
|
||||||
|
var ok bool
|
||||||
|
if ok, muxer, err = handler.ServerMuxer(uri); ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var ext string
|
var ext string
|
||||||
var u *url.URL
|
var u *url.URL
|
||||||
if u, _ = url.Parse(uri); u != nil && u.Scheme != "" {
|
if u, _ = url.Parse(uri); u != nil && u.Scheme != "" {
|
||||||
|
@ -25,7 +25,13 @@ import (
|
|||||||
|
|
||||||
var MaxProbePacketCount = 6
|
var MaxProbePacketCount = 6
|
||||||
|
|
||||||
func ParseURL(uri string) (u *url.URL) {
|
func ParseURL(uri string) (u *url.URL, err error) {
|
||||||
|
if u, err = url.Parse(uri); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, _, serr := net.SplitHostPort(u.Host); serr != nil {
|
||||||
|
u.Host += ":1935"
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,13 +41,9 @@ func Dial(uri string) (conn *Conn, err error) {
|
|||||||
|
|
||||||
func DialTimeout(uri string, timeout time.Duration) (conn *Conn, err error) {
|
func DialTimeout(uri string, timeout time.Duration) (conn *Conn, err error) {
|
||||||
var u *url.URL
|
var u *url.URL
|
||||||
|
if u, err = ParseURL(uri); err != nil {
|
||||||
if u, err = url.Parse(uri); err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if _, _, serr := net.SplitHostPort(u.Host); serr != nil {
|
|
||||||
u.Host += ":1935"
|
|
||||||
}
|
|
||||||
|
|
||||||
dailer := net.Dialer{Timeout: timeout}
|
dailer := net.Dialer{Timeout: timeout}
|
||||||
var netconn net.Conn
|
var netconn net.Conn
|
||||||
@ -301,7 +303,7 @@ func createURL(tcurl, app, play string) (u *url.URL) {
|
|||||||
out = append(out, s)
|
out = append(out, s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
path := strings.Join(out, "/")
|
path := "/"+strings.Join(out, "/")
|
||||||
u, _ = url.ParseRequestURI(path)
|
u, _ = url.ParseRequestURI(path)
|
||||||
|
|
||||||
if tcurl != "" {
|
if tcurl != "" {
|
||||||
@ -1740,6 +1742,16 @@ func (self *Conn) handshakeServer() (err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type closeConn struct {
|
||||||
|
*Conn
|
||||||
|
waitclose chan bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self closeConn) Close() error {
|
||||||
|
self.waitclose <- true
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func Handler(h *avutil.RegisterHandler) {
|
func Handler(h *avutil.RegisterHandler) {
|
||||||
h.UrlDemuxer = func(uri string) (ok bool, demuxer av.DemuxCloser, err error) {
|
h.UrlDemuxer = func(uri string) (ok bool, demuxer av.DemuxCloser, err error) {
|
||||||
if !strings.HasPrefix(uri, "rtmp://") {
|
if !strings.HasPrefix(uri, "rtmp://") {
|
||||||
@ -1749,5 +1761,87 @@ func Handler(h *avutil.RegisterHandler) {
|
|||||||
demuxer, err = Dial(uri)
|
demuxer, err = Dial(uri)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h.ServerMuxer = func(uri string) (ok bool, muxer av.MuxCloser, err error) {
|
||||||
|
if !strings.HasPrefix(uri, "rtmp://") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
|
||||||
|
var u *url.URL
|
||||||
|
if u, err = ParseURL(uri); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
server := &Server{
|
||||||
|
Addr: u.Host,
|
||||||
|
}
|
||||||
|
|
||||||
|
waitstart := make(chan error)
|
||||||
|
waitconn := make(chan *Conn)
|
||||||
|
waitclose := make(chan bool)
|
||||||
|
|
||||||
|
server.HandlePlay = func(conn *Conn) {
|
||||||
|
waitconn <- conn
|
||||||
|
<-waitclose
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
waitstart <- server.ListenAndServe()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err = <-waitstart:
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case conn := <-waitconn:
|
||||||
|
muxer = closeConn{Conn: conn, waitclose: waitclose}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h.ServerDemuxer = func(uri string) (ok bool, demuxer av.DemuxCloser, err error) {
|
||||||
|
if !strings.HasPrefix(uri, "rtmp://") {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ok = true
|
||||||
|
|
||||||
|
var u *url.URL
|
||||||
|
if u, err = ParseURL(uri); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
server := &Server{
|
||||||
|
Addr: u.Host,
|
||||||
|
}
|
||||||
|
|
||||||
|
waitstart := make(chan error)
|
||||||
|
waitconn := make(chan *Conn)
|
||||||
|
waitclose := make(chan bool)
|
||||||
|
|
||||||
|
server.HandlePublish = func(conn *Conn) {
|
||||||
|
waitconn <- conn
|
||||||
|
<-waitclose
|
||||||
|
}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
waitstart <- server.ListenAndServe()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err = <-waitstart:
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
case conn := <-waitconn:
|
||||||
|
demuxer = closeConn{Conn: conn, waitclose: waitclose}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user