5.5 KiB
LPMS - Livepeer media server
LPMS is a media server that can run independantly, or on top of the Livepeer network. It allows you to manipulate / broadcast a live video stream. Currently, LPMS supports RTMP as input format and RTMP/HLS as output formats.
LPMS can be integrated into another service, or run as a standalone service. To try LPMS as a standalone service, simply get the package:
go get github.com/livepeer/lpms
Go to the lpms root directory, and run
./lpms
Requirements
LPMS requires ffmpeg. To install it on OSX, use homebrew. As a part of this installation, ffmpeg and ffplay should be installed as commandline utilities.
//This may take a few minutes
brew install ffmpeg --with-fdk-aac --with-ffplay --with-freetype --with-libass --with-libquvi --with-libvorbis --with-libvpx --with-opus --with-x265
LPMS uses SRS as a transcoding backend. It's included in
the /bin directory for testing purposes. Make sure you are running SRS before testing out LPMS.
To start srs, run
./bin/srs -c ./bin/srs.conf
Testing out LPMS
The test LPMS server exposes a few different endpoints:
rtmp://localhost:1936/stream/testfor uploading/viewing RTMP video stream.http://localhost:8000/transcodefor issuing transcode request.http://localhost:8000/stream/test_tran.m3u8for consuming the transcoded video.
Do the following steps to view a live stream video:
- Upload an RTMP video stream to
rtmp://localhost:1936/stream/test. We recommend using OBS.
- If you have successfully uploaded the stream, you should see something like this in the LPMS output
I0324 09:44:14.639405 80673 listener.go:28] RTMP server got upstream
I0324 09:44:14.639429 80673 listener.go:42] Got RTMP Stream: test
- Now you have a RTMP video stream running, we can view it from the server. Simply run
ffplay rtmp://localhost:1936/stream/test, you should see the rtmp video playback. - Let's transcode the video to HLS. Before issuing the transcoding request, make sure your SRS is running.
//To start SRS
./bin/srs -c ./bin/srs.conf
- To issue the transcoding request, we can use curl.
curl -H "Content-Type: application/json" -X POST -d '{"StreamID":"test"}' http://localhost:8000/transcode
- You should see your SRS console start logging. Now just open up
hlsVideo.htmlin Safari, and you should see the HLS video. There may be a delay due to the video transcoding - we'll expose more parameters to lower that delay in the future. Note that in typical internet broadcasting today, there is usually a delay of 30 - 90 seconds.
Integrating LPMS
LPMS exposes a few different methods for customization. As an example, take a look at cmd/lpms.go.
To create a new LPMS server:
//Specify ports you want the server to run on, and which port SRS is running on (should be specified)
//in srs.conf
lpms := lpms.New("1936", "8000", "2436", "7936")
To handle RTMP publish:
lpms.HandleRTMPPublish(
//getStreamID
func(reqPath string) (string, error) {
return getStreamIDFromPath(reqPath), nil
},
//getStream
func(reqPath string) (*stream.Stream, error) {
streamID := getStreamIDFromPath(reqPath)
stream := stream.NewStream(streamID)
streamDB.db[streamID] = stream
return stream, nil
},
//finishStream
func(reqPath string) {
delete(streamDB.db, getStreamIDFromPath(reqPath))
})
To handle RTMP playback:
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
})
To handle transcode request:
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.NewStream(streamID + "_tran")
streamDB.db[newStream.StreamID] = newStream
return newStream, nil
})
To handle HLS playback:
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
}
if buffer == nil {
//Create the buffer and start copying the stream into the buffer
buffer = stream.NewHLSBuffer()
bufferDB.db[streamID] = buffer
ec := make(chan error, 1)
go func() { ec <- s.ReadHLSFromStream(buffer) }()
}
return buffer, nil
})
You can follow the development of LPMS and Livepeer @ our forum

