node package manager
Loosely couple your services. Use Orgs to version and reuse your code. Create a free org »

properjs-mediabox

MediaBox

A lightweight manager for HTML5 audio and video.

Installation

npm install properjs-mediabox --save-dev

Usage

var MediaBox = require( "properjs-mediabox" );
var mediaBox = new MediaBox();

Loading Video

You can load video explicitly using the addVideo method. The order for src indicates the order in which the browser will attempt to decide which file it can play.

mediaBox.addVideo({
    id: "my-video-keyname",
    src: [
        "my/video/path/to/file.webm",
        "my/video/path/to/file.mp4",
        "my/video/path/to/file.ogv"
    ],
    channel: "vid",
    // If you want to supply the <video> element 
    // One will be created for you if you do not 
    element: videoElement
});

Loading Audio

You can load audio explicitly using the addAudio method. The order for src indicates the order in which the browser will attempt to decide which file it can play.

mediaBox.addAudio({
    id: "my-audio-keyname",
    src: [
        "my/audio/path/to/file.mp3",
        "my/audio/path/to/file.ogg"
    ],
    channel: "sfx",
    // If audio is NOT on the same domain 
    CORS: true,
    // Handle the xhr onload event 
    onloaded: function ( buffer ) {
        // buffer = ArrayBuffer of audio data 
    }
});

Loading Bundles

You can bundle load media using the loadMedia method or the addMedia method.

mediaBox.loadMedia( "bundle.json", function () {
    // Do stuff here, like play some of the loaded media 
});
mediaBox.addMedia( bundle, function () {
    // Do stuff here, like play some of the loaded media 
});

Bundle Format

When bundling media, use the following format. You can load as many audio and video objects as you want, just add them to the arrays.

{
    "addAudio": [
        {
            "id": "my-audio-keyname",
            "src": [
                "my/audio/path/to/file.mp3",
                "my/audio/path/to/file.ogg"
            ],
            "channel": "bgm"
        }
    ],
 
    "addVideo": [
        {
            "id": "my-video-keyname",
            "src": [
                "my/video/path/to/file.webm",
                "my/video/path/to/file.mp4",
                "my/video/path/to/file.ogv"
            ],
            "channel": "vid"
        }
    ]
}

Using Channels

MediaBox uses channels to organize the media content. The default channels are vid, bgm and sfx respectively. You can add any extra number of channels you want, just pass them in the config. You can set channel specific properties, however, the only property used internally by MediaBox is the volume one. For instance, to adjust the levels for background music and sound effects:

// Assume your media has been loaded 
mediaBox.setChannelProp( "bgm", "volume", 0.5 );
mediaBox.setChannelProp( "sfx", "volume", 0.75 );

You can also stop and start an entire channel:

mediaBox.stopChannel( "bgm" );
mediaBox.playChannel( "bgm" );

As well as fade channels in and out:

mediaBox.fadeChannelIn( "bgm", 5000 );
mediaBox.fadeChannelOut( "bgm", 5000 );

Lastly, you can cross fade between a playing channel and a new object id you would like to play:

mediaBox.crossFadeChannel( "bgm", "my-new-sound", 3000 );

Example

This example puts all the pieces together, showing you how you can use MediaBox. It assumes you have an audio module that looks something like this:

<section class="audio js-audio" data-id="sick-sounds" data-src="/audio/sounds-of-sickness.mp3">
    <div class="audio__wrap">
        <div class="audio__button js-button">
            <div class="valigner">
                <div class="valigner__cell">
                    <span class="audio__play js-play">
                        <span class="icon icon--light icon--play-media icon--play-media--audio"></span>
                    </span>
                    <span class="audio__pause js-pause">
                        <span class="icon icon--light icon--pause-media icon--pause-media--audio"></span>
                    </span>
                </div>
            </div>
        </div>
        <div class="audio__track js-track">
            <div class="audio__waves">
                <canvas class="audio__waveform js-waveform" height="30" width="100%"></canvas>
                <div class="audio__fillmask js-fillmask">
                    <canvas class="audio__progress js-progress" height="30" width="100%"></canvas>
                </div>
            </div>
            <div class="audio__scrubber js-scrubber">
                <div class="audio__buffered js-buffered"></div>
            </div>
            <div class="audio__time js-time"></div>
            <div class="audio__duration js-duration"></div>
        </div>
    </div>
</section>

So then you could have some Javascript that tackles the task like this:

var mediabox = new MediaBox(),
    $audio = $( ".js-audio" ),
    $button = $audio.find( ".js-button" ),
    $buffered = $audio.find( ".js-buffered" ),
    $duration = $audio.find( ".js-duration" ),
    $waveform = $audio.find( ".js-waveform" ),
    $progress = $audio.find( ".js-progress" ),
    $fillmask = $audio.find( ".js-fillmask" ),
    $time = $audio.find( ".js-time" ),
    src = $audio.data( "src" ),
    id = $audio.data( "id" ),
    buffUp = function () {
        var duration = mediabox.getMediaProp( id, "duration" ),
            buffered = mediabox.getMediaProp( id, "buffered" );
 
        if ( buffered && buffered.length ) {
            buffered = buffered.end( 0 );
 
            if ( buffered === duration ) {
                clearInterval( buffIn );
            }
 
            $buffered[ 0 ].style.width = ((buffered / duration) * 100) + "%";
        }
    },
    buffIn = setInterval( buffUp, 200 );
 
mediabox.addAudio({
    id: id,
    src: src.split( "|" ),
    channel: "sfx",
    onloaded: function ( buffer ) {
        // You can create audio waveforms with the buffer 
        // var data = buffer.getChannelData( 0 ); 
 
        $audio.addClass( "is-loaded" );
 
        mediabox.playMedia( id );
    }
});
 
mediabox.addMediaEvent( id, "loadedmetadata", function () {
    var duration = mediabox.getMediaProp( id, "duration" );
 
    $time.text( "0:00" );
    $duration.text( parseTime( duration ) );
});
 
mediabox.addMediaEvent( id, "timeupdate", function () {
    var duration = mediabox.getMediaProp( id, "duration" ),
        ellapsed = mediabox.getMediaProp( id, "currentTime" );
 
    $fillmask[ 0 ].style.width = ((ellapsed / duration) * 100) + "%";
 
    $time.text( parseTime( ellapsed ) );
});
 
mediabox.addAudioEvent( id, "play", function () {
    $button.addClass( "is-playing" );
});
 
mediabox.addAudioEvent( id, "pause", function () {
    $button.removeClass( "is-playing" );
});
 
mediabox.addAudioEvent( id, "ended", function () {
    $button.removeClass( "is-playing" );
 
    $progress[ 0 ].style.width = px( 0 );
});

API

Loader API

  • loadMedia( url, callback )
  • addMedia( obj )
  • addVideo( obj )
  • addAudio( obj )

Channel API

  • setChannelProp( channel, prop, val )
  • getChannelProp( channel, prop )
  • playChannel( channel )
  • stopChannel( channel )
  • fadeChannelIn( channel, duration )
  • fadeChannelOut( channel, duration )
  • crossFadeChannel( channel, id, duration )
  • getChannels()

Abstract Audio/Video API

  • fadeMediaIn( id, duration )
  • fadeMediaOut( id, duration )
  • getVolume( id )
  • setVolume( id, val )
  • isLoaded( id )
  • isPaused( id )
  • isPlaying( id )
  • isStopped( id )
  • playMedia( id )
  • stopMedia( id )
  • pauseMedia( id )
  • destroyMedia( id )
  • getMediaProp( id, prop )
  • setMediaProp( id, prop, val )
  • getMediaAttr( id, attr )
  • setMediaAttr( id, attr, val )
  • addMediaEvent( id, event, callback )
  • removeMediaEvent( id, event )
  • getMedia( id )
  • getAudios()
  • getVideos()

Static API

  • MediaBox.support
  • MediaBox.STATE_PLAYING
  • MediaBox.STATE_STOPPED
  • MediaBox.STATE_PAUSED
  • MediaBox.STATE_STOPPING