{"id":16980243,"url":"https://github.com/jaygooby/keyframe-tweets","last_synced_at":"2026-05-08T08:11:59.704Z","repository":{"id":66731898,"uuid":"110043740","full_name":"jaygooby/keyframe-tweets","owner":"jaygooby","description":"Extracts i-frames as jpegs from an rtmp video stream for use with live tweeting","archived":false,"fork":false,"pushed_at":"2018-11-09T10:38:59.000Z","size":3,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-21T23:14:14.736Z","etag":null,"topics":[],"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/jaygooby.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":"2017-11-08T23:47:50.000Z","updated_at":"2018-11-09T10:39:01.000Z","dependencies_parsed_at":null,"dependency_job_id":"ea23cf16-d576-4bd8-aaee-c413687eee4a","html_url":"https://github.com/jaygooby/keyframe-tweets","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jaygooby/keyframe-tweets","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaygooby%2Fkeyframe-tweets","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaygooby%2Fkeyframe-tweets/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaygooby%2Fkeyframe-tweets/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaygooby%2Fkeyframe-tweets/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jaygooby","download_url":"https://codeload.github.com/jaygooby/keyframe-tweets/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jaygooby%2Fkeyframe-tweets/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32772165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T02:36:36.067Z","status":"ssl_error","status_checked_at":"2026-05-08T02:36:07.210Z","response_time":54,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":[],"created_at":"2024-10-14T01:50:30.399Z","updated_at":"2026-05-08T08:11:59.688Z","avatar_url":"https://github.com/jaygooby.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# About\nI'm using this system to extract images from a video stream so I can add the images to my live tweets, without needing to also hold a camera.\n\nThe ffmpeg command extracts [i-frames](https://en.wikipedia.org/wiki/Video_compression_picture_types#Intra-coded_.28I.29_frames.2Fslices_.28key_frames.29) so I should be able to capture slide changes, etc.\n\n# Components\nMy setup is an old iPhone 4 on a [tripod plus a zoom lens](https://www.amazon.co.uk/gp/product/B00AQUIBUA/ref=oh_aui_detailpage_o03_s00?ie=UTF8\u0026psc=1), running [Larix Broadcaster](https://wmspanel.com/larix_broadcaster) - a free app with no restrictions on broadcasting time. You don't need to use an iPhone; you just need a device that can push a video stream to an rtmp url; a Raspberry Pi with a camera would work just as well.\n\nThe Larix app sends an [rtmp](https://en.wikipedia.org/wiki/Real-Time_Messaging_Protocol) stream to an instance of [nginx](http://nginx.org/) running on my laptop that's been compiled with the [nginx rtmp streaming module](https://github.com/arut/nginx-rtmp-module). The [nginx config](./rtmp.conf) is really basic and just rebroadcasts this stream.\n\nIf you want to try this yourself, use my [build-nginx script](https://github.com/jaygooby/build-nginx) to get a custom nginx setup:\n\n```\nbuild-nginx -m https://github.com/arut/nginx-rtmp-module.git@v1.2.0\n```\n\nI then point [ffmpeg](https://www.ffmpeg.org/) at the nginx stream and it extracts the images into a folder named after the speaker; all this is done through a simple [Makefile](./Makefile).\n\nThe last component is the networking. I need the the iPhone to stream nicely to my laptop, and I don't want to rely on the venue wifi, and I can't use mobile data, because the rtmp stream needs to connect to my laptop's IP, so instead I've got a [Netgear N300 wifi range extender](https://www.amazon.co.uk/NETGEAR-Extender-External-Antennas-EX2700-100UKS/dp/B00NIUHAG6/ref=pd_lpo_vtph_147_bs_lp_tr_t_1?_encoding=UTF8\u0026psc=1\u0026refRID=8JRBPGWVJG39BS27H2JC) which both my laptop and the iPhone 4 connect to.\n\nI can configure the Netgear to use the venue wifi or use another phone's hotspot for the actual internet connection.\n\n# Capturing images from the video feed\n## Get the rtmp url\nYou'll need to know what RTMP URL to stream your video to. On the laptop where you'll be running nginx, use the Makefile to show it to you:\n\n```\nmake url\n```\n\nor if you know which network adapter you want to use:\n\n```\nETH=eth1 make url\n```\n\nThis will output a url like `rtmp://10.10.10.1/live/tweets` enter this into the Larix app (or whatever streaming video capture software you're using).\n\n## Start the capture\nNow you know the url, and presuming that you've started nginx and are now streaming video to it from your camera or device, you'll want to start grabbing frames.\n\nJust call:\n\n```\nmake\n```\n\nor again, if you're using a different adapter,\n\n```\nETH=eth1 make\n```\n\nThis will create a folder called something like `stills/1510321049` where the numerical directory is just the epoch seconds timestamp for when you ran the command.\n\nIf you'd like a nicer name, call it like this:\n\n```\nSPEAKER=jay make\n```\n\nThis will instead make a folder called `stills/jay` containing the video stills.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaygooby%2Fkeyframe-tweets","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjaygooby%2Fkeyframe-tweets","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjaygooby%2Fkeyframe-tweets/lists"}