Skip to content

Commit

Permalink
interface cleanup, segment transcoder
Browse files Browse the repository at this point in the history
  • Loading branch information
ericxtang committed Jul 2, 2017
1 parent e97eb09 commit d85c95a
Show file tree
Hide file tree
Showing 15 changed files with 640 additions and 338 deletions.
56 changes: 14 additions & 42 deletions cmd/rtmp_segment_packer/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,22 +121,6 @@ func (s *SegmentStream) ReadRTMPFromStream(ctx context.Context, dst av.MuxCloser
}
time.Sleep(time.Second * 1)
}

// for {
// packet := s.GetPacket()

// if len(packet.Data) == 0 {
// glog.Info("Reached the end...")
// dst.WriteTrailer()
// return io.EOF
// }
// err := dst.WritePacket(packet)
// if err != nil {
// glog.Infof("Error writing RTMP packet from Stream %v to mux", s.StreamID)
// return err
// }
// }

}

return nil
Expand Down Expand Up @@ -270,41 +254,29 @@ func main() {
streamDB := &StreamDB{db: make(map[string]stream.Stream)}

lpms.HandleRTMPPublish(
//getStreamID
func(url *url.URL) (string, error) {
return getStreamIDFromPath(url.Path), nil
//makeStreamID
func(url *url.URL) (strmID string) {
return getStreamIDFromPath(url.Path)
},
//getStream
func(url *url.URL) (stream.Stream, stream.Stream, error) {
//gotStream
func(url *url.URL, rtmpStrm *stream.VideoStream) error {
streamID := getStreamIDFromPath(url.Path)
stream1 := NewSegmentStream(streamID)
stream2 := NewSegmentStream(streamID)
// stream2 := NewSegmentStream(streamID)
streamDB.db[streamID] = stream1
return stream1, stream2, nil
return nil
},
//finishStream
func(strmID1 string, strmID2 string) {
// streamID := getStreamIDFromPath(reqPath)
// delete(streamDB.db, streamID)
// tranStreamID := streamID + "_tran"
// delete(streamDB.db, tranStreamID)
//endStream
func(url *url.URL, rtmpStrm *stream.VideoStream) error {
delete(streamDB.db, rtmpStrm.GetStreamID())
return nil
})

lpms.HandleRTMPPlay(
//getStream
func(ctx context.Context, reqPath string, dst av.MuxCloser) error {
glog.Infof("Got req: ", reqPath)
// streamID := getStreamIDFromPath(reqPath)
// src := streamDB.db[streamID]
func(url *url.URL) (stream.Stream, error) {
src := copyStream(&StagedStream)

// if src != nil {
src.ReadRTMPFromStream(ctx, dst)
// } else {
// glog.Error("Cannot find stream for ", streamID)
// return stream.ErrNotFound
// }
return nil
return src, nil
})

lpms.HandleTranscode(
Expand All @@ -324,7 +296,7 @@ func main() {
fileStream := stream.NewFileStream(streamID + "_file")
return fileStream, nil
})
lpms.Start()
lpms.Start(context.Background())
}

func getStreamIDFromPath(reqPath string) string {
Expand Down
149 changes: 67 additions & 82 deletions cmd/runner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ package main
import (
"context"
"flag"
"fmt"
"net/http"
"net/url"
"regexp"
"strings"
"time"

"github.com/ericxtang/m3u8"
"github.com/golang/glog"
"github.com/livepeer/lpms"
"github.com/livepeer/lpms/stream"

"github.com/nareix/joy4/av"
)

type StreamDB struct {
Expand All @@ -23,6 +23,25 @@ type BufferDB struct {
db map[string]*stream.HLSBuffer
}

//Trivial method for getting the id
func getStreamID(url *url.URL) string {
if strings.HasSuffix(url.Path, "m3u8") {
return "hlsStrmID"
} else {
return "rtmpStrmID"
}
}

func getHLSSegmentName(url *url.URL) string {
var segName string
regex, _ := regexp.Compile("\\/stream\\/.*\\.ts")
match := regex.FindString(url.Path)
if match != "" {
segName = strings.Replace(match, "/stream/", "", -1)
}
return segName
}

func main() {
flag.Set("logtostderr", "true")
flag.Parse()
Expand All @@ -32,89 +51,55 @@ func main() {
bufferDB := &BufferDB{db: make(map[string]*stream.HLSBuffer)}

lpms.HandleRTMPPublish(
//getStreamID
func(url *url.URL) (string, error) {
return getStreamIDFromPath(url.Path), nil
//makeStreamID
func(url *url.URL) (strmID string) {
//Give the stream a name
return getStreamID(url)
},
//getStream
func(url *url.URL) (stream.Stream, stream.Stream, error) {
rtmpStreamID := getStreamIDFromPath(url.Path)
hlsStreamID := rtmpStreamID + "_hls"
rtmpStream := stream.NewVideoStream(rtmpStreamID, stream.RTMP)
hlsStream := stream.NewVideoStream(hlsStreamID, stream.HLS)
streamDB.db[rtmpStreamID] = rtmpStream
streamDB.db[hlsStreamID] = hlsStream
return rtmpStream, hlsStream, nil
//gotStream
func(url *url.URL, rtmpStrm *stream.VideoStream) (err error) {
//Store the stream
streamDB.db[rtmpStrm.GetStreamID()] = rtmpStrm
return nil
},
//finishStream
func(rtmpID string, hlsID string) {
delete(streamDB.db, rtmpID)
delete(streamDB.db, hlsID)
//endStream
func(url *url.URL, rtmpStrm *stream.VideoStream) error {
//Remove the stream
delete(streamDB.db, rtmpStrm.GetStreamID())
return nil
})

//No transcoding for now until segment transcoder is finished.
// lpms.HandleTranscode(
// //getInStream
// func(ctx context.Context, streamID string) (stream.Stream, error) {
// if stream := streamDB.db[streamID]; stream != nil {
// return stream, nil
// }

// return nil, stream.ErrNotFound
// },
// //getOutStream
// func(ctx context.Context, streamID string) (stream.Stream, error) {
// //For this example, we'll name the transcoded stream "{streamID}_tran"
// newStream := stream.NewVideoStream(streamID + "_tran")
// streamDB.db[newStream.GetStreamID()] = newStream
// return newStream, nil

// // glog.Infof("Making File Stream")
// // fileStream := stream.NewFileStream(streamID + "_file")
// // return fileStream, nil
// })

lpms.HandleHLSPlay(
//getHLSBuffer
func(reqPath string) (*stream.HLSBuffer, error) {
streamID := getHLSStreamIDFromPath(reqPath)
// glog.Infof("Got HTTP Req for stream: %v", streamID)
buffer := bufferDB.db[streamID]
s := streamDB.db[streamID]

if s == nil {
return nil, stream.ErrNotFound
//getMasterPlaylist
func(url *url.URL) (*m3u8.MasterPlaylist, error) {
//No need to return a masterlist unless we are doing ABS
return nil, nil
},
//getMediaPlaylist
func(url *url.URL) (*m3u8.MediaPlaylist, error) {
buf, ok := bufferDB.db[getStreamID(url)]
if !ok {
return nil, fmt.Errorf("Cannot find video")
}

if buffer == nil {
//Create the buffer and start copying the stream into the buffer
buffer = stream.NewHLSBuffer(10, 100)
bufferDB.db[streamID] = buffer
sub := stream.NewStreamSubscriber(s)
go sub.StartHLSWorker(context.Background(), time.Second*1)
err := sub.SubscribeHLS(streamID, buffer)
if err != nil {
return nil, stream.ErrStreamSubscriber
}
return buf.LatestPlaylist()
},
//getSegment
func(url *url.URL) ([]byte, error) {
buf, ok := bufferDB.db[getStreamID(url)]
if !ok {
return nil, fmt.Errorf("Cannot find video")
}

return buffer, nil
return buf.WaitAndPopSegment(context.Background(), getHLSSegmentName(url))
})

lpms.HandleRTMPPlay(
//getStream
func(ctx context.Context, reqPath string, dst av.MuxCloser) error {
glog.Infof("Got req: ", reqPath)
streamID := getStreamIDFromPath(reqPath)
src := streamDB.db[streamID]

if src != nil {
src.ReadRTMPFromStream(ctx, dst)
} else {
glog.Error("Cannot find stream for ", streamID)
return stream.ErrNotFound
}
return nil
func(url *url.URL) (stream.Stream, error) {
glog.Infof("Got req: ", url.Path)
strmID := getStreamID(url)
src := streamDB.db[strmID]

return src, nil
})

//Helper function to print out all the streams
Expand All @@ -133,13 +118,13 @@ func main() {
w.Write([]byte(str))
})

lpms.Start()
lpms.Start(context.Background())
}

func getStreamIDFromPath(reqPath string) string {
return "test"
}
// func getStreamIDFromPath(reqPath string) string {
// return "test"
// }

func getHLSStreamIDFromPath(reqPath string) string {
return "test_hls"
}
// func getHLSStreamIDFromPath(reqPath string) string {
// return "test_hls"
// }
Loading

0 comments on commit d85c95a

Please sign in to comment.