{"id":22677871,"url":"https://github.com/leask/jsmpeg","last_synced_at":"2025-03-29T12:44:56.447Z","repository":{"id":150323433,"uuid":"58945648","full_name":"Leask/jsmpeg","owner":"Leask","description":null,"archived":false,"fork":false,"pushed_at":"2016-05-16T16:09:38.000Z","size":1208,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-02-04T13:43:53.113Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/Leask.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":"2016-05-16T15:54:27.000Z","updated_at":"2021-11-18T21:28:37.000Z","dependencies_parsed_at":"2023-04-19T03:38:54.408Z","dependency_job_id":null,"html_url":"https://github.com/Leask/jsmpeg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leask%2Fjsmpeg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leask%2Fjsmpeg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leask%2Fjsmpeg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Leask%2Fjsmpeg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Leask","download_url":"https://codeload.github.com/Leask/jsmpeg/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246187219,"owners_count":20737460,"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-12-09T18:02:51.751Z","updated_at":"2025-03-29T12:44:56.442Z","avatar_url":"https://github.com/Leask.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"jsmpeg\n==========\n\n#### An MPEG1 Video Decoder in JavaScript ####\n\njsmpeg is a MPEG1 Decoder, written in JavaScript. It's \"hand ported\", i.e. not compiled with\nemscripten or similar. This will probably make it obsolete with the advent of asmjs.\n\nSome demos and more info: [phoboslab.org/log/2013/05/mpeg1-video-decoder-in-javascript](http://www.phoboslab.org/log/2013/05/mpeg1-video-decoder-in-javascript)\n\n\n### Usage ###\n\n```javascript\n// Synopsis: var player = new jsmpeg(urlToFile, options);\n// The 'options' argument and all of its properties is optional. If no canvas element \n// is given, jsmpeg will create its own, to be accessed at .canvas\n\n// Example:\nvar canvas = document.getElementById('videoCanvas');\nvar player = new jsmpeg('file.mpeg', {canvas: canvas, autoplay: true, loop: true});\n\nplayer.pause();\nplayer.play();\nplayer.stop();\n\n\n// If you pass 'seekable: true' in the options, you can seek to a specific frame\n// or time in the video.\n\nvar player = new jsmpeg('file.mpeg', {canvas: canvas, seekable: true});\n\nplayer.seekToFrame(1200); // Seek to intra frame before frame 1200\nplayer.seekToTime(20); // Seek to intra frame before 20sec\n\n// seekToFrame() and seekToTime() only seek to the closest, previous intra frame by\n// default. If you want to seek to the exact frame or time, pass 'true' as second\n// parameter.\n// Depending on the input video, this can be potentially slow, as jsmpeg has\n// to decode all frames between the previous intra frame and the seek target\n\nplayer.seekToFrame(1200, true); // Seek to frame 1200 exactly\n\n\n// Passing 'seekable: true' also populates the total frame count and duration\n// of the video\n\nconsole.log('Duration: '+player.duration+' seconds ('+player.frameCount+' frames)')\n\n\n\n// An 'onload' callback can be specified in the 'options' argument\nvar mpegLoaded = function( player ) {\n\tconsole.log('Loaded', player);\n};\nvar player = new jsmpeg('file.mpeg', {onload: mpegLoaded});\n\n// If you don't use 'autoplay' and don't explicitly call .play(), you can get individual\n// video frames (a canvas element) like so:\nvar frame = null;\nwhile( (frame = player.nextFrame()) ) {\n\tsomeOtherCanvasContext.drawImage(frame, 0, 0);\n}\n```\n\n### Live Streaming ###\n\njsmpeg supports streaming live video through WebSockets. You can use ffmpeg and a nodejs server to serve the MPEG video. See this [blog post](http://phoboslab.org/log/2013/09/html5-live-video-streaming-via-websockets) for the details of setting up a server. Also have a look at the `stream-server.js` and `stream-example.html`.\n\nTo configure jsmpeg to connect to the stream server, simply pass a WebSocket connection instead of a filename to the constructor:\n\n```javascript\n// Setup the WebSocket connection and start the player\nvar client = new WebSocket( 'ws://example.com:8084/' );\nvar player = new jsmpeg(client, {canvas:canvas});\n```\n\n###Stream Recording###\n\nTo record an MPEG stream clientside in the browser jsmpeg provides the `.startRecording(cb)` and `.stopRecording()` methods. `.stopRecording()` returns a `Blob` object that can be used to create a download link.\n\n```javascript\nplayer.startRecording(function(player){\n\t// Called when recording really starts; usually \n\t// when the next intra frame is received\n});\n\n// ...\n\n// Stop recording and create a download link\nvar blob = player.stopRecording();\n\nvar filename = 'jsmpeg-recording.mpg';\nvar a = document.getElementById('downloadLink');\na.innerHTML = filename;\na.download = fileName;\na.href = window.URL.createObjectURL(blob);\n```\n\n\n\n### Limitations ###\n\n- Playback can only start when the file is fully loaded (when not streaming through WebSockets). I'm waiting for chunked XHR with ArrayBuffers to arrive in browsers.\n- MPEG files with B-Frames look weird - frames are not reordered. This should be relatively easy\nto fix, but most encoders seem to not use B-Frames at all by default.\n- The width of the MPEG video has to be a multiple of 2.\n- Only raw MPEG video streams are supported. The decoder hates Stream Packet Headers in between\nmacroblocks.\n\nYou can use [FFmpeg](http://www.ffmpeg.org/) to encode videos in a suited format. This will crop\nthe size to a multiple of 2, omit B-Frames and force a raw video stream:\n\n```\nffmpeg -i in.mp4 -f mpeg1video -vf \"crop=iw-mod(iw\\,2):ih-mod(ih\\,2)\" -b 0 out.mpg\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleask%2Fjsmpeg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleask%2Fjsmpeg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleask%2Fjsmpeg/lists"}