Code Monkey home page Code Monkey logo

streamana's Introduction

Streamana

Description

Streamana is a Web page which streams your camera and microphone to YouTube Live (or any other HLS or DASH receiver). It uses webm-muxer.js and ffmpeg.js.

Demo

You can see it in action here. Use Chrome 95 or later.

  1. Get your ingestion URL from YouTube Studio.

    1. Click CREATE and then select Go Live from the drop-down menu.

    2. Under Select stream key, select Create new stream key.

    3. Give your key a name.

    4. You must select HLS as the streaming protocol. Note: YouTube DASH ingestion is only available by using the Youtube API. See here for more details.

    5. Click CREATE.

    6. Make sure the key you created is selected.

    7. Click COPY next to Stream URL.

  2. Paste the URL into the Ingestion URL box in Streamana.

  3. Click Live.

    • If you want to see what’s happening under the hood, open developer tools (F12).

  4. To end the stream, click Live again.

You can also change various options:

  • Mute and unmute your microphone by clicking on the microphone symbol.

  • Hide and show your camera by clicking on the camera symbol.

  • Under the drop-down menu (top-left):

    • Change the camera resolution.

    • Convert your camera’s video to greyscale.

    • Lock the camera to portrait mode (where available, e.g. mobile phones).

    • Zoom the camera to fill the page.

    • Switch between HLS and DASH encoding.

    • Switch between POST and PUT requests.

    • Switch between CORS modes.

    • Switch between MediaRecorder and WebCodecs.

    • Select a different version of ffmpeg.js to perform the HLS or DASH encoding.

Customisation

You can change the look and feel of Streamana by editing site/streamana.html and site/streamana.css.

The camera video is passed through a WebGL fragment shader in site/shader.js so you can change this to add video effects or overlays. The shader already handles resizing and rotating the video in main(). The optional greyscale conversion is in the tpix() function.

The page’s functionality is defined in site/streamana.js and site/streamer.js.

site/streamer.js exports a function, get_default_config_from_url, and a class, Streamer, which does the heavy lifting.

You should first call get_default_config_from_url. It takes a single argument, the URL of ffmpeg-worker-hls.js or ffmpeg-worker-dash.js in ffmpeg.js. This allows your application (or the end user if required) to supply its own version, in accordance with LGPL. It can be a relative path (i.e. just ffmpeg-worker-hls.js or ffmpeg-worker-dash.js).

get_default_config_from_url determines the streaming protocol (hls or dash) and returns the default configuration for the protocol:

{
    ffmpeg_lib_url, // the URL you passed to `get_default_config_from_url`
    protocol, // `hls` or `dash`
    video: { // properies of the video you will be supplying
        bitrate: 2500 * 1000,
        framerate: 30
    },
    audio: { // properties of the audio you will be supplying
        bitrate: 128 * 1000
    },
    media_recorder: { // default options for MediaRecorder if it ends up being used
        video: {
            codec: protocol === 'dash' ? 'vp9' : 'H264', // video codec
        },
        audio: {
            codec: 'opus' // audio codec
        },
        webm: true, // container format
        mp4: false // if true, requires ffmpeg-worker-hls.js or ffmpeg-worker-dash.js
                   // to be configured with MP4 support (which is not the default)
    },
    webcodecs: { // default options for WebCodecs if it ends up being used
        video: {
            // video codec and options
            ...(protocol === 'dash' ? {
                codec: 'vp09.00.10.08.01'
            } : {
                codec: 'avc1.42E01E' /*'avc1.42001E'*/,
                avc: { format: 'annexb' }
            })
        },
        audio: {
            codec: 'opus' /*'pcm'*/, // audio codec
        },
        webm_muxer: { // options for webm-muxer.js
            video: {
                codec: protocol === 'dash' ? 'V_VP9' : 'V_MPEG4/ISO/AVC'
            },
            audio: {
                codec: 'A_OPUS',
                bit_depth: 0 // 32 for pcm */
            }
        }
    },
    ffmpeg: { // desired ffmpeg output codecs
        // Note: If the encoded stream already uses the desired codec then
        // it will pass `copy` instead. For example, if your browser encodes
        // your video to H.264 already then `copy` will be used instead of
        // `libx264`. This means you can use `ffmpeg-worker-hls.js` or
        // `ffmpeg-worker-dash.js` that doesn't contain a H.264 encoder.
        video: {
            codec: protocol === 'dash' ? 'libvpx-vp9' : 'libx264'
        },
        audio: {
            codec: protocol === 'dash' ? 'libopus' : 'aac'
        }
    }
};

You application can modify the returned configuration before creating a Streamer object.

Use the Streamer class as follows:

  • The constructor takes the following arguments:

    • The MediaStream containing your video and audio tracks. Note that site/streamana.js supplies blank video when the camera is hidden and silent audio when the microphone is muted.

    • An AudioContext instance. This is used to create a persistent audio generator for triggering updates to avoid browser timer throttling. If you don’t already use one in your application, you can just new AudioContext().

    • The ingestion URL.

    • The configuration returned by calling get_default_config_from_url (see above), optionally modified by your application.

    • Whether the video is rotated.

    • Extra request options for fetch. You can use this to override the default request method (POST) or CORS mode (no-cors).

    • Whether to encode audio and video using WebCodecs (true) or MediaRecorder (false).

  • Call the async start() method to start streaming.

  • Call the end() method to stop streaming.

Streamer extends from EventTarget and dispatches the following events:

  • start when streaming has started.

  • update, dispatched frame rate times a second. site/streamana.js reacts to this event by refreshing the WebGL canvas from the camera.

  • exit when streaming has stopped.

  • error if an error occurs.

Licence

Streamana is licensed under the terms of the MIT licence.

Note that ffmpeg.js is licensed under LGPL. Streamana runs it inside a Web Worker and communicates with it via message passing. The end user can replace the version used by changing the URL in the user interface.

Note also that the ffmpeg.js HLS and DASH distributions contain no H.264 or MP4 code. All encoding is done by the browser using MediaRecorder or WebCodecs.

streamana's People

Contributors

davedoesdev avatar

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.