Coder Social home page Coder Social logo

webm.js's Introduction

Create WebM videos in your browser. No server-side, pure JavaScript.

Build Status


What's this?

webm.js is a simple one-page application that allows you to convert videos to WebM format right into your browser, without any plugins or server-side involved. It is built upon FFmpeg, libvpx and libopus which were ported to JavaScript using Emscripten. Since WebM is part of HTML5 stack, why can't we create one without leaving the browser?

Try it

Latest build of webm.js is available here. NOTE: built-in video player uses software decoding in order to play any video it can encode and thus experimental and slow.

Tested browsers:

  • Firefox: fast enough to encode several minutes of SD/HD video within half of hour
  • Chrome: a bit slower than FF but still good
  • Edge: a bit slower than FF but still good (make sure to enable asm.js in about:flags)
  • IE11: several times slower than Edge and will fail on big files but otherwise works

Take also look at demo and screenshots.

Is it fast?

Well, partly. With the help of asm.js, generic code compiled by Emscripten is almost as fast as native, but JavaScript doesn't have access to advanced x86 instructions like SSE and codecs use them far and wide so we have some performance degradation here. Not that drastical though—I had numbers like 8x worse than native@corei7-avx for libvpx-vp8 and ~4 fps (single thread, SD, medium settings). Low-level multithreading is also not available in stable versions of browsers, but luckily we can hack it up by splitting video into chunks and encoding them in separate workers.

To get you some concrete numbers: it takes ~5m25s to encode sample clip (860x484, 1m9s) with default settings (2pass, -threads 4 -c:v libvpx -b:v 885k -speed 1 -auto-alt-ref 1 -lag-in-frames 25 -c:a libopus -b:a 64k) at i7 3820. Same encode with native FFmpeg/libvpx takes ~40s. Hopefully we will improve that performance with WebAssembly and SIMD.js, stay tuned!

What about quality?

Currently only VP8+Opus combination is supported. Opus is better than Vorbis (and almost any other lossy audio codec) for the full range of bitrates and encoder is blazingly fast. Unfortunately, due to lack of SIMD, libvpx-vp9 encoder is rather impractical in browser and VP8 is significantly worse than VP9. Though JavaScript SIMD API is part of ES7 proposal and already supported by Firefox Nightly so I'm actively looking into this.

Trying to compensate the use of outdated codec, two-pass encoding with speed=1 and lag-in-frames=25 is used. Splitting video in parts creates additional keyframes and therefore loses effeciency a bit, but the difference should be negligible for the g=128 currently used. It is also possible to specify speed=0 or quality=best and other FFmpeg/libvpx options if you're trying to achieve the maximal quality.

How to start hacking?

Build your own version of webm.js is as simple as clone the repo and run

npm i && npm run release

inside. Host the dist directory with your favourite HTTP server or use npm start to start the development server at 8080 port.

I want to use it locally and don't have node.js

No problem! Just download webm.js-gh-pages.zip, unpack it and open index.html with Firefox. Everything should work right away. Other browsers will require local HTTP server, run python -mSimpleHTTPServer in unpacked directory if in doubt.

It's also perfectly possible to build browser extension, user script or even embed WebM encoder into your site. I haven't done anything in that direction yet, but let me know if you're interested.

License

webm.js own code, documentation, favicon and logo licensed under CC0, but the resulting build also includes the following libraries and assets:


webm.js - JavaScript WebM encoder

Written in 2015 by Kagami Hiiragi [email protected]

To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide. This software is distributed without any warranty.

You should have received a copy of the CC0 Public Domain Dedication along with this software. If not, see http://creativecommons.org/publicdomain/zero/1.0/.

webm.js's People

Contributors

kagami avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

webm.js's Issues

关于webrtc的问题(On the problem of webrtc)

我用js的getusermedia方法获取到了视频流 但是我想分割成多段视频 用常规的方法slice 出现了 只有第一段可以播放 于是我了解到需要在视频上加头信息 谁可以帮我写段js代码 在视频上加信息 让所有的视频都可以正常的播放
I used the JS getusermedia method to get the video stream, but I wanted to split it into multiple segments of video using the conventional method, slice appeared only the first paragraph, so I learned that I needed to add the header information on the video who could help me write a segment of the JS code to add information to the video so that all the visual frequency could be played normally.

Can't convert IVA file

I am using Zeranoe's Windows build of ffmpeg to convert IVA files from a security camera so I can view them. Here is the session I ran and the result -

D:\Downloads\ffmpeg-20160913-c19da0c-win64-static\bin

ffmpeg.exe -analyzeduration 1 -probesize 1000 -i "00-201304050008-0076.IVA" -c:v mpeg4 -map:v 0 "00-201304050008-0076.mp4"
ffmpeg version N-81646-gc19da0c Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.4.0 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-dx
va2 --enable-libmfx --enable-nvenc --enable-avisynth --enable-bzlib --enable-lib
ebur128 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --ena
ble-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfree
type --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enab
le-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-lib
openh264 --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschr
oedinger --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheor
a --enable-libtwolame --enable-libvidstab --enable-libvo-amrwbenc --enable-libvo
rbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --ena
ble-libx265 --enable-libxavs --enable-libxvid --enable-libzimg --enable-lzma --e
nable-decklink --enable-zlib
libavutil 55. 29.100 / 55. 29.100
libavcodec 57. 55.101 / 57. 55.101
libavformat 57. 48.103 / 57. 48.103
libavdevice 57. 0.102 / 57. 0.102
libavfilter 6. 62.100 / 6. 62.100
libswscale 4. 1.100 / 4. 1.100
libswresample 2. 1.100 / 2. 1.100
libpostproc 54. 0.100 / 54. 0.100
[avi @ 0000000000586fc0] Something went wrong during header parsing, I will igno
re it and try to continue anyway.
[avi @ 0000000000586fc0] Stream #0: not enough frames to estimate rate; consider
increasing probesize
[avi @ 0000000000586fc0] Could not find codec parameters for stream 0 (Video: no
ne (ITVD / 0x44565449), none, 320x240): unknown codec
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Guessed Channel Layout for Input Stream #0.1 : stereo
Input #0, avi, from 'U:\Case Files\Kamali_v_CalTrans\Evidence\00-201304050008-00
76.IVA':
Duration: 00:01:20.00, start: 0.000000, bitrate: 1677 kb/s
Stream #0:0: Video: none (ITVD / 0x44565449), none, 320x240, 30 fps, 30 tbr,
30 tbn, 30 tbc
Stream #0:1: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, 2 channels,
s16, 1411 kb/s
File 'U:\Case Files\Kamali_v_CalTrans\Evidence\00-201304050008-0076.mp4' already
exists. Overwrite ? [y/N] y
No decoder for stream #0:0, filtering impossible
Error opening filters!

+++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++

Here is part of the actual .IVA file (NULLs and other non-printing characters removed)

RIFF<!XAVI LISTŠithdivah~P00-201304050008-0076.IVA¼ýtÀ¹€|ÌvLM¥0°‘1Îð%ã·˜1Î@ðITVD++LISTŽhdrlavih85‚ð@ðLIST¤strlstrh8vidsITVDÿÿÿÿ@ðstrf((@ðITVDindx(00dcúISTŽstrlstrh8auds±@Õ5@Õ5strf(D¬±indx(01wbzD LIST|strlstrh8cccsstrfindx(02ccšµLIST|strlstrh8wwmmstrfindx(03wm¼JUNKêLIST@!Xmoviix00x=

+++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++

I have tried various versions of the command line from the simplest just giving the names of the input and output files to specifying codecs as well as settings for -analyzeduration and -probesize with no success.

Thanks for any help.
Richard

Duration N/A wem

I got next error , my file was uploaded by BLOBS and joined them using CONCAT-FILES for some reason i can play this videos but it doesn't have a final time.

[opus @ 0x789a90] Warning: not compiled with thread support, using thread emulation
[vp8 @ 0x78a240] Warning: not compiled with thread support, using thread emulation
Input #0, matroska,webm, from '/data/in.webm':
Metadata:
encoder : Chrome
Duration: N/A, start: 0.000000, bitrate: N/A
Stream #0:0(eng): Audio: opus, 48000 Hz, mono, fltp (default)
Stream #0:1(eng): Video: vp8, yuv420p, 640x480, SAR 1:1 DAR 4:3, 30 fps, 30 tbr, 1k tbn, 1k tbc (default)
At least one output file must be specified

Should we still be using this project?

Hello, I noticed that the source hasnt been updated in 5 years. Are the ffmpeg versions and dependencies up to date?

Currently attempting a 3 min .mp4 conversion and it's taking a very long time (> 15 mins).

No intermediate status lines in Edge

Video thread log shows:

$ ffmpeg -ss 0 -hide_banner -i in.webm -c:v libvpx -b:v 885k -speed 4 -auto-alt-ref 1 -lag-in-frames 25 -sn -c:a libopus -b:a 64k -ac 2 -an -pass 1 -f null -t 17 -
[vp8 @ 0x72b3a0] Warning: not compiled with thread support, using thread emulation
[vorbis @ 0x72bac0] Warning: not compiled with thread support, using thread emulation
Input #0, matroska,webm, from 'in.webm':
  Metadata:
    encoder         : Lavf56.40.100
  Duration: 00:01:09.00, start: 0.000000, bitrate: 1683 kb/s
    Stream #0:0: Video: vp8, yuv420p, 853x480, SAR 1:1 DAR 853:480, 24 fps, 24 tbr, 1k tbn, 1k tbc (default)
    Stream #0:1: Audio: vorbis, 48000 Hz, stereo, fltp (default)
[libvpx @ 0x73a450] Warning: not compiled with thread support, using thread emulation
[libvpx @ 0x73a450] v1.4.0
[vp8 @ 0x72da60] Warning: not compiled with thread support, using thread emulation
Output #0, null, to 'pipe:':
  Metadata:
    encoder         : Lavf56.36.100
    Stream #0:0: Video: vp8 (libvpx), yuv420p, 853x480 [SAR 1:1 DAR 853:480], q=-1--1, pass 1, 885 kb/s, 24 fps, 24 tbn, 24 tbc (default)
    Metadata:
      encoder         : Lavc56.41.100 libvpx
Stream mapping:
  Stream #0:0 -> #0:0 (vp8 (native) -> vp8 (libvpx))
Press [q] to stop, [?] for help

and it just stops there (no CPU usage ongoing either), whereas on Firefox it continues running and displays output about frame size/speed/etc.

Minimize memory consumption

Things currently broken:

  • Subtitles rendering, process hungs
  • Encoding the entire file, audio/last video processes hungs

Things still causing out of memory:

  • ~400M fails at info stage
  • ~200M fails while encoding

What can be done?

  • Small -max_alloc helps at info stage
  • -blocksize ?
  • Some advanced ffmpeg options/try to patch?
  • Compile with ALLOW_MEMORY_GROWTH, bench results?

It's not possible to encode some H.264 videos

No matter what type of video I try I get the error: Metadata parser failed with the following error: ArrayBuffer.isView is not a function
There's no log. I tested it and it worked perfectly in Firefox.

Limit maximum bitrate?

Auto-calculation of bitrate with small durations (<10s) results in gigantic values which cause some slowdown. Constant quality works faster in that case. Probably some bitrate constraints should be used in limit mode.

Second run in the same worker cause "Out of memory" in Edge

For some reason Edge doesn't like the second run of main function in the same worker and cancels it with Out of memory. Interesting enough, IE11 works fine in that case. It might be result of bug in current implementation of asm.js in Edge.

This can be workarounded by respawning Prober's worker on each run of analyze and decode methods. While it's rather ok to respawn analyzer to be safe against already running issues, it will make software player even slower.

Encode fails immediately on 2nd pass with "Cannot enlarge memory arrays."

Attempting to encode 10 seconds of a video, the first pass (thread 1) finishes without problems, but then the second pass fails immediately.

Test cases: 720p mp4 (failed, logs attached), 720p mp4 (failed), 360p mp4 (encoded successfully)
Options chosen: 10 second duration, 2 threads, otherwise defaults.

Main log:

[18:49:33] Spawning jobs:
[18:49:33]   2 video thread(s)
[18:49:33]   1 audio thread
[18:49:33] Video 1 started first pass
[18:49:33] Video 2 started first pass
[18:49:33] Audio started
[18:49:41] Audio finished (00:00:07.1)
[18:50:40] Video 1 finished first pass (00:01:06.1)
[18:50:40] Video 1 started second pass
[18:50:44] Fatal error at Video 1: Uncaught abort("Cannot enlarge memory arrays. Either (1) compile with -s TOTAL_MEMORY=X with X higher than the current value 67108864, (2) compile with ALLOW_MEMORY_GROWTH which adjusts the size at runtime but prevents some optimizations, or (3) set Module.TOTAL_MEMORY before the program runs.") at Error
    at Error (native)
    at xa (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:12:141)
    at E (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:25:196)
    at Function.g.Oa [as Rd] (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:35:165)
    at Aa (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:18:24)
    at wNa (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:4838:6988)
    at oHa (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:4827:213617)
    at SKa (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:4824:122774)
    at Array.VKa (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:4824:134263)
    at Object.gRa [as dynCall_vii] (https://kagami.github.io/webm.js/1527e3d81b.ffmpeg-worker-webm.js:4838:121823)
If this abort() is unexpected, build with -s ASSERTIONS=1 which can give more information.

Video 1 Log:

$ ffmpeg -hide_banner -ss 0 -i in.mp4 -t 5 -c:v libvpx -b:v 6489k -speed 4 -auto-alt-ref 1 -lag-in-frames 25 -sn -c:a libopus -b:a 64k -ac 2 -an -pass 1 -f null -
[h264 @ 0x747b40] Warning: not compiled with thread support, using thread emulation
[aac @ 0x74ed30] Warning: not compiled with thread support, using thread emulation
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'in.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-12-23 17:25:06
  Duration: 00:02:04.97, start: 0.000000, bitrate: 1916 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1264x720, 1721 kb/s, 23.98 fps, 23.98 tbr, 48k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
    Metadata:
      creation_time   : 2013-12-23 17:25:06
      handler_name    : IsoMedia File Produced by Google, 5-11-2011
[libvpx @ 0x76cd40] Warning: not compiled with thread support, using thread emulation
[libvpx @ 0x76cd40] v1.4.0
[h264 @ 0x769d20] Warning: not compiled with thread support, using thread emulation
Output #0, null, to 'pipe:':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    encoder         : Lavf56.36.100
    Stream #0:0(und): Video: vp8 (libvpx), yuv420p, 1264x720, q=-1--1, pass 1, 6489 kb/s, 23.98 fps, 23.98 tbn, 23.98 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc56.41.100 libvpx
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> vp8 (libvpx))
Press [q] to stop, [?] for help
frame=    3 fps=0.0 q=0.0 size=N/A time=00:00:00.00 bitrate=N/A    
frame=    5 fps=3.9 q=0.0 size=N/A time=00:00:00.00 bitrate=N/A    
frame=    7 fps=3.4 q=0.0 size=N/A time=00:00:00.00 bitrate=N/A    
frame=    9 fps=3.3 q=0.0 size=N/A time=00:00:00.00 bitrate=N/A    

[ ... Cut ... ]

frame=  120 fps=2.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A    
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded 
$ ffmpeg -hide_banner -ss 0 -i in.mp4 -t 5 -c:v libvpx -b:v 6489k -speed 1 -auto-alt-ref 1 -lag-in-frames 25 -sn -c:a libopus -b:a 64k -ac 2 -an -pass 2 1.webm
[h264 @ 0x747b20] Warning: not compiled with thread support, using thread emulation
[aac @ 0x74ed10] Warning: not compiled with thread support, using thread emulation
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'in.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2013-12-23 17:25:06
  Duration: 00:02:04.97, start: 0.000000, bitrate: 1916 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1264x720, 1721 kb/s, 23.98 fps, 23.98 tbr, 48k tbn, 47.95 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
    Metadata:
      creation_time   : 2013-12-23 17:25:06
      handler_name    : IsoMedia File Produced by Google, 5-11-2011
[libvpx @ 0x76d210] Warning: not compiled with thread support, using thread emulation
[libvpx @ 0x76d210] v1.4.0

Video 2 and Audio logs not attached as they seem to be typical (although Video 2 only got 80 frames into the encode)

Can this be used to make WebP's from static images?

As I understand it WebP is just a single frame of WebM. Can this library do that?

I'd love to see some examples for how to perform WebM conversion too. I am pretty sure this is the only library on the web that does pure JS WebM encoding and it's awesome.

Out of memory in IE11

IE11 doesn't like the current memory defaults (128M for decoder, 256M for encoder) and fails when trying to encode more than 1 second of sample (0.1 second works fine). VM has 8G of memory.

Currently I set TOTAL_MEMORY to 64M for IE <= 11, but it may be worth to search for better defaults/solution. Unfortunately we can't make this fully customizable because file prober runs at the startup and IE11 still fails on 128M decoder + 64M encoder.

Software player performance

I'm going to replace HTML5 player with software one, powered by ffmpeg's decoders, in order to be able to play and edit any video files. Realtime decoding is not that important since user may select heavyweight sources but it may be worth to think whether we can optimize it a bit.

I will start with simple and slow one-ffmpeg-call-per-one-frame, later we can try to adapt some ideas from ogv.js project.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.