{"id":13582060,"url":"https://github.com/livepeer/lpms","last_synced_at":"2025-04-06T11:32:34.686Z","repository":{"id":38430441,"uuid":"80242947","full_name":"livepeer/lpms","owner":"livepeer","description":"Livepeer media server","archived":false,"fork":false,"pushed_at":"2025-03-15T16:09:47.000Z","size":241603,"stargazers_count":285,"open_issues_count":56,"forks_count":72,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-30T22:58:38.510Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/livepeer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-27T20:22:35.000Z","updated_at":"2025-03-15T16:09:50.000Z","dependencies_parsed_at":"2024-01-18T11:45:26.949Z","dependency_job_id":"1c128bcc-f61c-4817-a98c-ba791216f492","html_url":"https://github.com/livepeer/lpms","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livepeer%2Flpms","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livepeer%2Flpms/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livepeer%2Flpms/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/livepeer%2Flpms/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/livepeer","download_url":"https://codeload.github.com/livepeer/lpms/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247478132,"owners_count":20945257,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T15:02:24.584Z","updated_at":"2025-04-06T11:32:34.674Z","avatar_url":"https://github.com/livepeer.png","language":"Go","funding_links":[],"categories":["Others","Go","HarmonyOS"],"sub_categories":["Windows Manager"],"readme":"![Build status](https://github.com/livepeer/lpms/actions/workflows/linux.yml/badge.svg?branch=master)\n\n# LPMS - Livepeer Media Server\n\nLPMS is a media server that can run independently, or on top of the [Livepeer](https://livepeer.org)\nnetwork. It allows you to manipulate / broadcast a live video stream. Currently, LPMS supports RTMP\nas input format and RTMP/HLS as output formats.\n\nLPMS can be integrated into another service, or run as a standalone service. To try LPMS as a\nstandalone service, simply get the package:\n\n```sh\ngo get -d github.com/livepeer/lpms/cmd/example\n```\n\nGo to the lpms root directory at `$GOPATH/src/github.com/livepeer/lpms`. If needed, install the required dependencies; see the Requirements section below. Then build the sample app and run it:\n\n```sh\ngo build cmd/example/main.go\n./example\n```\n\n### Requirements\n\nLPMS requires libavcodec (ffmpeg) and friends. See `install_ffmpeg.sh` . Running this script will install everything in `~/compiled`. In order to build LPMS, the dependent libraries need to be discoverable by pkg-config and golang. If you installed everything with `install_ffmpeg.sh` , then run `export PKG_CONFIG_PATH=~/compiled/lib/pkgconfig:$PKG_CONFIG_PATH` so the deps are picked up.\n\nRunning golang unit tests (`test.sh`) requires the `ffmpeg` and `ffprobe` executables in addition to the libraries. To ensure the executables are available, run `export PATH=~/compiled/bin:$PATH`. Additionally it requires ffmpeg to be build with additional codecs and formats enabled. To build `ffmpeg` with all codecs and formats enabled, ensure `clang` is installed and then run `BUILD_TAGS=debug-video ./install_ffmpeg.sh`. However, none of these are run-time requirements; the executables are not used outside of testing, and the libraries are statically linked by default. Note that dynamic linking may substantially speed up rebuilds if doing heavy development.\n\n### Testing out LPMS\n\nThe test LPMS server exposes a few different endpoints:\n\n1. `rtmp://localhost:1935/stream/test` for uploading/viewing RTMP video stream.\n2. `http://localhost:7935/stream/test_hls.m3u8` for consuming the HLS video stream.\n\nDo the following steps to view a live stream video:\n\n1. Start LPMS by running `go run cmd/example/main.go`\n2. Upload an RTMP video stream to `rtmp://localhost:1935/stream/test`. We recommend using ffmpeg or [OBS](https://obsproject.com/download).\n\n   For ffmpeg on osx, run: `ffmpeg -f avfoundation -framerate 30 -pixel_format uyvy422 -i \"0:0\" -c:v libx264 -tune zerolatency -b:v 900k -x264-params keyint=60:min-keyint=60 -c:a aac -ac 2 -ar 44100 -f flv rtmp://localhost:1935/stream/test`\n\n   For OBS, fill in Settings-\u003eStream-\u003eURL to be rtmp://localhost:1935\n\n3. If you have successfully uploaded the stream, you should see something like this in the LPMS output\n\n   ```bash\n   I0324 09:44:14.639405   80673 listener.go:28] RTMP server got upstream\n   I0324 09:44:14.639429   80673 listener.go:42] Got RTMP Stream: test\n   ```\n\n4. Now you have a RTMP video stream running, we can view it from the server. Simply run `ffplay http://localhost:7935/stream/test.m3u8`, you should see the hls video playback.\n\n### Integrating LPMS\n\nLPMS exposes a few different methods for customization. As an example, take a look at `cmd/main.go`.\n\nTo create a new LPMS server:\n\n```go\n// Specify ports you want the server to run on, and the working directory for\n// temporary files. See `core/lpms.go` for a full list of LPMSOpts\nopts := lpms.LPMSOpts {\n    RtmpAddr: \"127.0.0.1:1935\",\n    HttpAddr: \"127.0.0.1:7935\",\n    WorkDir:  \"/tmp\"\n}\nlpms := lpms.New(\u0026opts)\n```\n\nTo handle RTMP publish:\n\n```go\nlpms.HandleRTMPPublish(\n\t//getStreamID\n\tfunc(url *url.URL) (strmID string) {\n\t\treturn getStreamIDFromPath(reqPath)\n\t},\n\t//getStream\n\tfunc(url *url.URL, rtmpStrm stream.RTMPVideoStream) (err error) {\n\t\treturn nil\n\t},\n\t//finishStream\n\tfunc(url *url.URL, rtmpStrm stream.RTMPVideoStream) (err error) {\n\t\treturn nil\n\t})\n```\n\nTo handle RTMP playback:\n\n```go\nlpms.HandleRTMPPlay(\n\t//getStream\n\tfunc(ctx context.Context, reqPath string, dst av.MuxCloser) error {\n\t\tglog.Infof(\"Got req: \", reqPath)\n\t\tstreamID := getStreamIDFromPath(reqPath)\n\t\tsrc := streamDB.db[streamID]\n\t\tif src != nil {\n\t\t\tsrc.ReadRTMPFromStream(ctx, dst)\n\t\t} else {\n\t\t\tglog.Error(\"Cannot find stream for \", streamID)\n\t\t\treturn stream.ErrNotFound\n\t\t}\n\t\treturn nil\n\t})\n```\n\nTo handle HLS playback:\n\n```go\nlpms.HandleHLSPlay(\n\t//getHLSBuffer\n\tfunc(reqPath string) (*stream.HLSBuffer, error) {\n\t\tstreamID := getHLSStreamIDFromPath(reqPath)\n\t\tbuffer := bufferDB.db[streamID]\n\t\ts := streamDB.db[streamID]\n\n\t\tif s == nil {\n\t\t\treturn nil, stream.ErrNotFound\n\t\t}\n\n\t\tif buffer == nil {\n\t\t\t//Create the buffer and start copying the stream into the buffer\n\t\t\tbuffer = stream.NewHLSBuffer()\n\t\t\tbufferDB.db[streamID] = buffer\n\n            //Subscribe to the stream\n\t\t\tsub := stream.NewStreamSubscriber(s)\n\t\t\tgo sub.StartHLSWorker(context.Background())\n\t\t\terr := sub.SubscribeHLS(streamID, buffer)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, stream.ErrStreamSubscriber\n\t\t\t}\n\t\t}\n\n\t\treturn buffer, nil\n\t})\n```\n\n### GPU Support\n\nProcessing on Nvidia GPUs is supported. To enable this capability, FFmpeg needs\nto be built with GPU support. See the\n[FFmpeg guidelines](https://trac.ffmpeg.org/wiki/HWAccelIntro#NVENCNVDEC) on\nthis.\n\nTo execute the nvidia tests within the `ffmpeg` directory, run this command:\n\n```sh\ngo test --tags=nvidia -run Nvidia\n\n```\n\nTo run the tests on a particular GPU, use the GPU_DEVICE environment variable:\n\n```sh\n# Runs on GPU number 3\nGPU_DEVICE=3 go test --tags=nvidia -run Nvidia\n```\n\nAside from the tests themselves, there is a\n[sample program](https://github.com/livepeer/lpms/blob/master/cmd/transcoding/transcoding.go)\nthat can be used as a reference to the LPMS GPU transcoding API. The sample\nprogram can select GPU or software processing via CLI flags. Run the sample\nprogram via:\n\n```sh\n# software processing\ngo run cmd/transcoding/transcoding.go transcoder/test.ts P144p30fps16x9,P240p30fps16x9 sw\n\n# nvidia processing, GPU number 2\ngo run cmd/transcoding/transcoding.go transcoder/test.ts P144p30fps16x9,P240p30fps16x9 nv 2\n```\n\n### Testing GPU transcoding with failed segments from Livepeer production environment\n\nTo test transcoding of segments failed on production in Nvidia environment:\n\n1. Install Livepeer from sources by following the [installation guide](https://docs.livepeer.org/guides/orchestrating/install-go-livepeer#build-from-source)\n2. Install [Google Cloud SDK](https://cloud.google.com/sdk/docs/install-sdk)\n3. Make sure you have access to the bucket with the segments\n4. Download the segments:\n\n   ```sh\n   gsutil cp -r gs://livepeer-production-failed-transcodes /home/livepeer-production-failed-transcodes\n   ```\n\n5. Run the test\n\n   ```sh\n   cd transcoder\n   FAILCASE_PATH=\"/home/livepeer-production-failed-transcodes\" go test --tags=nvidia -timeout 6h -run TestNvidia_CheckFailCase\n   ```\n\n6. After the test has finished, it will display transcoding stats. Per-file results are logged to `results.csv` in the same directory\n\n### Contribute\n\nThank you for your interest in contributing to LPMS!\n\nTo get started:\n\n- Read the [contribution guide](doc/contributing.md)\n- Check out the [open issues](https://github.com/livepeer/lpms/issues)\n- Join the #dev channel in the [Discord](https://discord.gg/livepeer)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flivepeer%2Flpms","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flivepeer%2Flpms","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flivepeer%2Flpms/lists"}