{"id":13735734,"url":"https://github.com/leandromoreira/live-stream-from-desktop","last_synced_at":"2026-03-01T05:34:36.542Z","repository":{"id":49501776,"uuid":"129094181","full_name":"leandromoreira/live-stream-from-desktop","owner":"leandromoreira","description":"Provide guidance to test live streaming (mpeg-dash or hls) or vod from your desktop","archived":false,"fork":false,"pushed_at":"2024-06-17T22:20:48.000Z","size":3266,"stargazers_count":187,"open_issues_count":2,"forks_count":26,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-30T12:33:41.451Z","etag":null,"topics":["ffmpeg","hls","live-streaming","mpeg-dash","testing"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leandromoreira.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2018-04-11T13:00:12.000Z","updated_at":"2025-04-16T03:09:32.000Z","dependencies_parsed_at":"2024-05-08T01:45:28.546Z","dependency_job_id":"7e70ead8-b072-42d1-8907-79ca5af0aa9e","html_url":"https://github.com/leandromoreira/live-stream-from-desktop","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/leandromoreira/live-stream-from-desktop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Flive-stream-from-desktop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Flive-stream-from-desktop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Flive-stream-from-desktop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Flive-stream-from-desktop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leandromoreira","download_url":"https://codeload.github.com/leandromoreira/live-stream-from-desktop/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandromoreira%2Flive-stream-from-desktop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29960432,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T01:47:18.291Z","status":"online","status_checked_at":"2026-03-01T02:00:07.437Z","response_time":124,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ffmpeg","hls","live-streaming","mpeg-dash","testing"],"created_at":"2024-08-03T03:01:10.465Z","updated_at":"2026-03-01T05:34:36.520Z","avatar_url":"https://github.com/leandromoreira.png","language":"Shell","funding_links":[],"categories":["Learning Resources","testing"],"sub_categories":[],"readme":"# Live stream from your desktop\nIt provides guidance to test live streaming (mostly RTMP, SRT, mpeg-dash or hls) or vod from your own desktop using [FFmpeg](https://ffmpeg.org/), it's pretty useful for testing and learning purposes.\n\n## MacOS\n\n\u003e #### Tested with:\n\u003e * MacOS High Siera 10.13, 10.15.2, Ubuntu 18.04\n\u003e * **Warning:** The video asset used for looping streaming is more than hundreds of MBs.\n\n### Requirements\n\n```bash\ndocker\nwget\ncurl\n```\n### Simulating HLS / DASH with multiple renditions/resolutions and DVR\n\n#### HLS\n\nRun this server in one of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_http_server.sh | sh\n```\nRun this encoder in another of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_hls_abr_live_stream.sh | sh\n```\nAccess the stream at http://localhost:8080/master.m3u8 or at [clappr's demo page](http://clappr.io/demo/#dmFyIHBsYXllckVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGxheWVyLXdyYXBwZXIiKTsKCnZhciBwbGF5ZXIgPSBuZXcgQ2xhcHByLlBsYXllcih7CiAgc291cmNlOiAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL21hc3Rlci5tM3U4JywKICBwb3N0ZXI6ICdodHRwOi8vY2xhcHByLmlvL3Bvc3Rlci5wbmcnLAogIG11dGU6IHRydWUsCiAgaGVpZ2h0OiAzNjAsCiAgd2lkdGg6IDY0MAp9KTsKCnBsYXllci5hdHRhY2hUbyhwbGF5ZXJFbGVtZW50KTsK)\n\n##### HLS looping the file\n\n**If you want to use a video file instead of a synthetic media**, run this encoder in another of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_hls_abr_live_stream_file_loop.sh | sh\n```\n\n#### DASH\n\nRun this server in one of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_http_server.sh | sh\n```\nRun this encoder in another of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_dash_abr_live_stream.sh | sh\n```\nAccess the stream at http://localhost:8080/out.mpd or go to [dashjs's demo page](http://reference.dashif.org/dash.js/v2.3.0/samples/dash-if-reference-player/index.html?mpd=http://localhost:8080/out.mpd)\n\n### Simulating an HLS and MPEG-DASH live streaming for latency comparison\n\n#### HLS\n\nRun this server in one of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_http_server.sh | sh\n```\nRun this encoder in another of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_hls_low_latency_live_stream.sh | sh\n```\nAccess the stream at http://localhost:8080/stream.m3u8 or at [clappr's demo page](http://clappr.io/demo/#dmFyIHBsYXllckVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgicGxheWVyLXdyYXBwZXIiKTsKCnZhciBwbGF5ZXIgPSBuZXcgQ2xhcHByLlBsYXllcih7CiAgc291cmNlOiAnaHR0cDovL2xvY2FsaG9zdDo4MDgwL3N0cmVhbS5tM3U4JywKICBwb3N0ZXI6ICdodHRwOi8vY2xhcHByLmlvL3Bvc3Rlci5wbmcnLAogIGhsc2pzQ29uZmlnOiB7bGl2ZVN5bmNEdXJhdGlvbkNvdW50OiAyfSwKICBhdXRvUGxheTogdHJ1ZSwKICBtdXRlOiB0cnVlLAogIGhlaWdodDogMzYwLAogIHdpZHRoOiA2NDAKfSk7CgpwbGF5ZXIuYXR0YWNoVG8ocGxheWVyRWxlbWVudCk7Cgp2YXIgcCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKTsKcC5zdHlsZS5jc3NUZXh0ID0gInotaW5kZXg6IDk5OTk5OTsgcG9zaXRpb246YWJzb2x1dGU7IHJpZ2h0OjA7IHRvcDowOyBmb250LXNpemU6IDM0cHg7IGNvbG9yOiBibGFjazsgYmFja2dyb3VuZC1jb2xvcjogd2hpdGU7IiA7CmRvY3VtZW50LmJvZHkucHJlcGVuZChwKTsKbXlJbnRlcnZhbElEID0gc2V0SW50ZXJ2YWwoKCk9PiBwLmlubmVyVGV4dCA9IG5ldyBEYXRlKCkudG9Mb2NhbGVTdHJpbmcoKSwgMTAwMCk7)\n\n\n#### MPEG-DASH\n\nRun this server in one of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_http_server.sh | sh\n```\nRun this encoder in another of your tabs:\n```bash\ncurl -s https://raw.githubusercontent.com/leandromoreira/live-stream-from-desktop/master/start_mpeg_dash_low_latency_live_stream.sh | sh\n```\nAccess the stream at http://localhost:8080/stream.mpd\n\n### Requirements\n\n```bash\n# I assume you have brew already\n\n# or you could use curl\nbrew install wget\nbrew install ffmpeg\nbrew install node\n\n# the http server\nnpm install http-server -g\n\n#  WARNING IT IS A HUGE download file (263M)\nwget -O bunny_1080p_30fps.mp4 http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4\n\n```\n\n### Sending live RTMP from your local machine\n\n#### Single Bitrate \n\nFrom a pseudo FFmpeg video source color bar and generated audio signal made of a sine wave with amplitude 1/8. \n\n```\nffmpeg -hide_banner \\\n-re -f lavfi -i \"testsrc2=size=1280x720:rate=30,format=yuv420p\" \\\n-f lavfi -i \"sine=frequency=1000:sample_rate=4800\" \\\n-c:v libx264 -preset ultrafast -tune zerolatency -profile:v high \\\n-b:v 1400k -bufsize 2800k -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n-c:a aac -b:a 128k -f flv rtmp://\u003cHOST\u003e:1935/live/\u003cSTREAM\u003e\n```\n\nFrom a file. \n\n```\nffmpeg -stream_loop -1 \\\n-re -i \u003cYOUR_VIDEO\u003e.mp4  -c:v libx264 \\\n-x264opts keyint=30:min-keyint=30:scenecut=-1 -tune zerolatency \\\n-s 1280x720 -b:v 1400k -bufsize 2800k \\\n-f flv rtmp://\u003cHOST\u003e:1935/live/\u003cSTREAM\u003e\n```\n\n#### Multiple Bitrates \n\nFrom a pseudo FFmpeg video source color bar and generated audio signal made of a sine wave with amplitude 1/8. \n\n```\nffmpeg -hide_banner \\\n-re -f lavfi -i \"testsrc2=size=1280x720:rate=30,format=yuv420p\" \\\n-f lavfi -i \"sine=frequency=1000:sample_rate=4800\" \\\n-c:v libx264 -preset ultrafast -tune zerolatency -profile:v high \\\n-b:v 1400k -bufsize 2800k -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n-c:a aac -b:a 128k -f flv rtmp://\u003cHOST\u003e:1935/live/\u003cSTREAM\u003e \\\n-c:v libx264 -preset ultrafast -tune zerolatency -profile:v high \\\n-b:v 750k -bufsize 1500k -s 640x360 -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n-c:a aac -b:a 128k -f flv rtmp://\u003cHOST\u003e:1935/live/\u003cSTREAM\u003e \n```\n\nFrom a file. \n\n```\nffmpeg -stream_loop -1 \\\n-re -i \u003cYOUR_VIDEO\u003e.mp4  -c:v libx264 \\\n-x264opts keyint=30:min-keyint=30:scenecut=-1 -tune zerolatency \\\n-s 1280x720 -b:v 1400k -bufsize 2800k \\\n-f flv rtmp://\u003cHOST\u003e:1935/live/\u003cSTREAM\u003e \\\n-x264opts keyint=30:min-keyint=30:scenecut=-1 -tune zerolatency \\\n-s 640x360 -b:v 750k -bufsize 1500k \\\n-f flv rtmp://\u003cHOST\u003e:1935/live/\u003cSTREAM\u003e\n```\n\n### Simulating a MPEG-DASH live streaming from a file\n\nOpen a terminal and run the ffmpeg command:\n\n```\nffmpeg -stream_loop -1 -re -i bunny_1080p_30fps.mp4 \\\n       -c:v libx264 -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n       -preset superfast -profile:v baseline -level 3.0 \\\n       -tune zerolatency -s 1280x720 -b:v 1400k \\\n       -bufsize 1400k -use_timeline 1 -use_template 1 \\\n       -init_seg_name init-\\$RepresentationID\\$.mp4 \\\n       -min_seg_duration 2000000 -media_seg_name test-\\$RepresentationID\\$-\\$Number\\$.mp4 \\\n       -f dash stream.mpd\n```\n\nIn another tab, run the following command to fire up the server:\n\n```\nhttp-server -a :: -p 8081 --cors -c-1\n```\n\nNow you can test this with your player (using the URL `http://localhost:8081/stream.mpd`).\n\n### Simulating an HLS live streaming from a file\n\nOpen a terminal and run the ffmpeg command:\n\n```\nffmpeg -stream_loop -1 -re -i bunny_1080p_30fps.mp4 -c:v libx264 \\\n          -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n          -tune zerolatency -s 1280x720 \\\n          -b:v 1400k -bufsize 1400k \\\n          -hls_start_number_source epoch -f hls stream.m3u8\n```\n\nIn another tab, run the following command to fire up the server:\n\n```\nhttp-server -a :: -p 8081 --cors -c-1\n```\n\nNow you can test this with your player (using the URL `http://localhost:8081/stream.m3u8`).\n\n### Simulating a MPEG-DASH live streaming from MacOS camera\n\nOpen a terminal and run the ffmpeg command:\n\n```\nffmpeg -re -pix_fmt uyvy422 -f avfoundation -i \"0\" -pix_fmt yuv420p \\\n       -c:v libx264 -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n       -preset superfast -profile:v baseline -level 3.0 \\\n       -tune zerolatency -s 1280x720 -b:v 1400k \\\n       -bufsize 1400k -use_timeline 1 -use_template 1 \\\n       -init_seg_name init-\\$RepresentationID\\$.mp4 \\\n       -min_seg_duration 2000000 -media_seg_name test-\\$RepresentationID\\$-\\$Number\\$.mp4 \\\n       -f dash stream.mpd\n```\n\nIn another tab, run the following command to fire up the server:\n\n```\nhttp-server -a :: -p 8081 --cors -c-1\n```\n\nNow you can test this with your player (using the URL `http://localhost:8081/stream.mpd`).\n\n### Simulating a HLS live streaming from MacOS camera\n\n\n#### Playing Camera/Mic in FFplay\n\n```\nffplay  -f avfoundation -video_device_index 0 -audio_device_index 0 \\\n        -pixel_format uyvy422 -framerate 30 -video_size 1280x720 -i \"default\"\n```\n\n#### MacOS Camera/Mic to HLS\n\nOpen a terminal and run the ffmpeg command:\n\n```\nffmpeg  -f avfoundation -video_device_index 0 -audio_device_index 0 \\\n        -pixel_format uyvy422 -framerate 30 -video_size 640x480 -i \"default\" \\\n        -c:v libx264 -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n        -tune zerolatency -b:v 1000k -bufsize 2000k \\\n        -c:a aac -b:a 128k \\\n        -hls_time 5 -hls_start_number_source epoch \\\n        -f hls stream.m3u8\n```\n\nIn another tab, run the following command to fire up the server:\n\n```\nhttp-server -a :: -p 8081 --cors -c-1\n```\n\nNow you can test this with your player (using the URL `http://localhost:8081/stream.m3u8`).\n\n\n### MacOS Camera/Mic to Twitch/Youtube/RTMP\n\nOpen a terminal and run the ffmpeg command:\n\n```\nffmpeg  -f avfoundation -video_device_index 0 -audio_device_index 0 \\\n        -pixel_format uyvy422 -framerate 30 -video_size 640x480 -i \"default\" \\\n        -c:v libx264 -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n        -tune zerolatency -b:v 600k -bufsize 1200k -preset superfast \\\n        -c:a aac -b:a 128k \\\n        -f flv rtmp://yourserver:1935/live/yourstream_key\n```\n\n### Simulating an RTMP live streaming listening server with FFmpeg\n\n```bash\n#!/bin/bash\n# this is necessary since ffmpeg stop listening once a player drops\nwhile true\ndo\n        ffmpeg -hide_banner -loglevel verbose \\\n          -re -f lavfi -i testsrc2=size=1280x720:rate=30,format=yuv420p \\\n          -f lavfi -i sine=frequency=1000:sample_rate=44100 \\\n          -c:v libx264 -preset veryfast -tune zerolatency -profile:v baseline \\\n          -vf \"drawtext=text='RTMP streaming':box=1:boxborderw=10:x=(w-text_w)/2:y=(h-text_h)/2:fontsize=128:fontcolor=black\" \\\n          -b:v 1000k -bufsize 2000k -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n          -c:a aac -b:a 128k \\\n          -f flv -listen 1 -rtmp_live live \"rtmp://0.0.0.0:1935/live/app\"\n\tsleep 0.4\ndone\n\n```\n\n### Simulating an SRT live streaming\n\n```bash\nffmpeg -hide_banner -loglevel verbose \\\n    -re -f lavfi -i \"testsrc2=size=1280x720:rate=30,format=yuv420p\" \\\n    -f lavfi -i \"sine=frequency=1000:sample_rate=44100\" \\\n    -c:v libx264 -preset veryfast -tune zerolatency -profile:v baseline \\\n    -b:v 1000k -bufsize 2000k -x264opts keyint=30:min-keyint=30:scenecut=-1 \\\n    -f mpegts \"srt://0.0.0.0:1234?mode=listener\u0026smoother=live\u0026transtype=live\"\n```\n\n# Bonus Round:\n\n## FFmpeg generating sample files for testing purpose\n\nYou can replace codecs, duration, text, and parameters (resolution, sample rate, presets, and so on) to attend your needs. Here's 10.5 seconds clip.\n\n```bash\nffmpeg -y -hide_banner -loglevel verbose \\\n    -f lavfi -i 'testsrc2=size=768x432:duration=10.5:rate=30,format=yuv420p' \\\n    -f lavfi -i 'sine=frequency=1000:duration=10.5:sample_rate=44100' \\\n    -c:v libx264 -preset veryfast -tune zerolatency -profile:v baseline \\\n    -vf \"drawtext=text='Sample Test H264/AAC':box=1:boxborderw=10:x=(w-text_w)/2:y=(h-text_h)/2:fontsize=64:fontcolor=black\" \\\n    -b:v 1000k -bufsize 1000k -x264opts 'keyint=30:min-keyint=30:scenecut=-1' \\\n    -c:a aac -b:a 128k \\\n    sample_10.5s_h246_30fps_768x432_aac_44100.mp4\n```\n\n## FFmpeg generating noise from /dev/random\n\nIt generates video and audio from [/dev/urandom](https://en.wikipedia.org/wiki//dev/random) device, it produces a stream that looks A LOT like [an old analog TV noise](https://en.wikipedia.org/wiki/Noise_(video)).\n\n\u003e In analog video and television, is a random dot pixel pattern of static displayed when no transmission signal is obtained by the antenna receiver\n\n```bash\n# if you mess with the -video_size you can have bigger/smaller noise patterns than this. :D\nffmpeg -f rawvideo -pixel_format rgb8 -video_size 640x360 \\\n       -framerate 60 -i /dev/urandom \\\n       -f u8 -ar 48100 -ac 1 -i /dev/urandom \\\n       -sws_flags neighbor -s 640x360 urandom.mp4       \n```\n\n![old tv noise](https://upload.wikimedia.org/wikipedia/commons/a/a8/TV_noise.jpg)\n\n\n## FFmpeg generating video from FFmpeg binary program\n\n```bash\n# you can replace the binary by any large binary chunk of data (library...)\nffmpeg -f rawvideo -pixel_format rgb8 -video_size 32x23 \\\n       -framerate 60 -i /usr/local/Cellar/ffmpeg/4.3_2/bin/ffmpeg \\\n       -f u8 -ar 48100 -ac 1 -i /usr/local/Cellar/ffmpeg/4.3_2/bin/ffmpeg \\\n       -sws_flags neighbor -s 640x360 -t 5s -pix_fmt yuv420p ffmpeg.mp4\n```\n\n## FFmpeg generating video from Mandelbrot set\n\n```bash\nffplay -f lavfi -i mandelbrot=size=640x320:rate=60 \\\n       -vf \"drawtext = text = 'UTC %{gmtime}':fontsize=24:fontcolor=white:boxcolor=black@0.5:x=(w-text_w)/2:y=4:box=1:boxborderw=5\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandromoreira%2Flive-stream-from-desktop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleandromoreira%2Flive-stream-from-desktop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandromoreira%2Flive-stream-from-desktop/lists"}