colthreepv / angular-media-player

AngularJS Directive that wraps <audio> or <video> tag exposing methods and properties to manipulate your player
http://colthreepv.github.io/angular-media-player/
MIT License
228 stars 71 forks source link

angular-media-player Build Status

AngularJS Directive that wraps <audio> or <video> tag exposing methods and properties to manipulate your player

examples on github pages: http://colthreepv.github.io/angular-media-player/

DEPRECATED: development stalled

This library has reached way more users than expected when I first developed it;
I am very happy of that, but this means it has higher contribution and testing requirements that I was expecting!

From what I could see there's another valid (and quite customizable) project in the angular world: videogular
I don't think it covers ALL the use cases but that is not the point, most of them are covered, and documentation is extensive.
There's an example of using it as audio player with playlist, and the project is definitely future-proof.

Project Idea

I've come across a lot of <audio> players on the web, many using Flash, many being easy-to-use, almost none of them being compatible with AngularJS.
What i really was looking for was a simple audio wrapper without the need to support browser which don't have audio tag support!
Means support for this project is the same as: HTML5 audio draft, jQuery is not necessary, and DOM manipulation is done only with jqLite (IE9+)
angular-media-player is html/css agnostic, meaning you can use it with your browser controls and default style, or bind the methods and properties in your own View

How-to use it in your project

Using bower:

$ bower install angular-media-player

Using github hosting:

<!-- non-minified for debugging -->
<script src="https://github.com/colthreepv/angular-media-player/raw/master//colthreepv.github.io/angular-media-player/dist/angular-media-player.js" type="text/javascript"></script>
<!-- minified -->
<script src="https://github.com/colthreepv/angular-media-player/raw/master//colthreepv.github.io/angular-media-player/dist/angular-media-player.min.js" type="text/javascript"></script>

Test coverage

At the moment IE passes only 8 tests of 20, most of them require an <audio> tag to work with .ogg files. test-coverage

IE supports only .mp3 files, works as expected if you use them.

Breaking changes with 0.5.x

If you find something is missing from this list please take a couple of minutes to open an Issue

What's new

The new documentation is on-going work, you can keep track of it being developed, but is not ready to be deployed yet.
And this time will be on gh-pages!

More tests are coming.

Getting Started

Examples here

This directive it's just a way to expose HTMLMediaElement properties and methods to an AngularJS application, so you have to use custom html and css in order to interface with the audio directive.

Basic Example

In your AngularJS application include in dependency injection mediaPlayer

angular.module('myApp', ['mediaPlayer'])
.controller('MyController', function ($scope) .......)

Then in the html:

<div ng-controller="MyController">
  <audio media-player="audio1" data-playlist="playlist1">
    <source src="http://upload.wikimedia.org/wikipedia/en/d/d0/Rick_Astley_-_Never_Gonna_Give_You_Up.ogg" type="audio/ogg">
  </audio>
  <span ng-show="audio1.playing">Player status: Playing</span>
  <span ng-show="!audio1.playing">Player status: Paused</span>
</div>

What happens here: a variable called audio1 gets created on the scope bound to the controller that holds the <audio> tag. That might be one of your specific controller, or, if you didn't define anyone, it will be $rootScope.

You can access those methods like this:

angular.module('myApp').controller('MyController', function ($scope) {

  // access properties
  console.log($scope.audio1.network);
  console.log($scope.audio1.ended);

  $scope.mySpecialPlayButton = function () {
    $scope.customText = 'I started angular-media-player with a custom defined action!';
    $scope.audio1.playPause();
  };
})

You can use the methods in the controller AND directly in the HTML (as shown in the snippet before), since they are exposed in the $scope.

Directive

media-player is a directive working as an attribute, it must be used either on an <audio>, or <video> tag.

Attributes

Those can be used as any AngularJS directive attributes notation

Those attributes have a one-way binding, the objects gets allocated in the parent scope.

playlist structure

Playlist is an Array containing sourceElement(s).
An sourceElement itself could be an Array of sourceObjects, or a single sourceObject, mimicking the <source> HTML draft

sourceObject structure:

{ src: 'http://some.where.com', type: 'mime/type', media: '.css.media.query' }

or alternatively

[
  { src: 'http://some.where.com', type: 'audio/ogg' },
  { src: 'http://some.where.com/lowquality', type: 'audio/ogg' },
  { src: 'http://some.where.com/crapquality', type: 'audio/ogg' },
  { src: 'http://some.where.com', type: 'audio/mpeg' },
]

For whoever wondering what media is: it's just a css media query, so the browser can pick which <source> tag to load.
It's recent news that media it's (probably) getting deprecated anyway

Exposed Methods

player.load([mediaElement, autoplay])

Parameter mediaElement type object, structure as specified above.
Parameter autoplay type boolean
Internal function called from the below methods, can still be accessed directly if want to, if no parameter is provided just calls the <audio> load method (means it starts buffering).

player.play([index], [selectivePlay])

NOTE: this is 0-based exactly as you refer to the elements of an Array.

Parameter index type number, referring to the playlist index (0...playlist.length-1)
You can force to play a specific song using the index param.

Parameter selectivePlay type boolean, when this is true will be only played the specified track

player.playPause([index], [selectivePlay])

NOTE: this is 0-based exactly as you refer to the elements of an Array.

Parameter index type number, referring to the playlist index (0...playlist.length-1)
If you playPause the same index twice it will alternate start and stop.

Parameter selectivePlay type boolean, when this is true will be only played the specified track

player.pause()

Pauses the player.

player.next([autoplay])

Parameter autoplay type boolean
Goes to next mediaElement if there is one in the playlist.
Autoplay behaviour is the following: If a song is already playing, it will change to the next mediaElement, and autoplay itas soon as it's loaded.
You can force the autoplay using the autoplay parameter.

player.prev([autoplay])

Parameter autoplay type boolean
Goes to previous mediaElement if there is one in the playlist. If a song is already playing, it will change to the previous mediaElement, and autoplay it as soon as it's loaded.
You can force the autoplay using the autoplay parameter.

player.toggleMute()

Toggles mute property.

player.setVolume(value)

Parameter value type number
This method is a setter for the volume property.
value is between 0.0 and 1.0, refer to MDN.

player.setPlaybackRate(value)

Parameter value type number
This method is a setter for the playbackRate property.
value is between 0.0 and 1.0, refer to MDN.

player.seek(value)

Parameter value can be type number or string
This method sets currentTime on the element.
value can be between 0.0 and max duration, or it can be expressed in HH:mm:ss string format.

Exposed Properties

player.name REMOVED

Default is audioplayer, it's the name-prefix used in the Events

player.playing

true or false

player.ended

true or false

player.network

'progress', 'stalled', 'suspend', undefined (at initialization).
This property is a sum-up of the network state, the value changes when the respective events gets fired.

player.currentTrack

NOTE: this is 1-based exactly as length property of an Array.

Tracks the position of the playing track, it might change during playing the same track due to pushing elements into playlistArray

player.tracks

NOTE: this is 0-based exactly as you refer to the elements of an Array.

Number of tracks in the playlist.

Properties from HTMLMediaElement

Some properties are just forwarded to the scope, but are unchanged HTMLMediaElement spec

player.currentTime
player.duration
player.muted
player.playbackRate
player.volume

Timeranges:
player.buffered
player.played
player.seekable

Note about currentTime updating system

Version 0.5.8 has a configurable throttle options.
The default is that timeupdate event gets throttled to trigger not more than once per second (so currentTime aswell, since it reflects timeupdate value).

Default value, already inside the library, if you want to change it, copy/paste and change values for your (ENTIRE) application:

angular.module('yourModule')
.value('mp.throttleSettings', {
  enabled: true,
  time: 1000
});

It can be disabled or enabled with a configurable timeout.

Additional Properties

The following properties refer to some HTMLMediaElement spec properties, but are formatted for handiness.
player.formatDuration hh:mm:ss version of player.duration
player.formatTime hh:mm:ss version of player.duration
player.loadPercent 0-100 version of player.buffered, it's just a number, not a TimeRange element.

Events

In case of need you can bind directly to the events generated by the browser.

This is done via wrappers, they just call angular.js jqLite methods:

WARNING: the events are not sent to the $rootScope anymore. Player namespacing is no more nocessary, thus removed.

Example:

angular.module('myApp',['mediaPlayer'])
.controller('MyController', function ($scope) {
  $scope.playerName.on('load', function (evt) {
    // Tell someone a song is gonna get loaded.
  });
})

Playlist Behaviour

You can add/remove tracks on-fly from/to the playlist.
If the current track gets removed, the player goes on pause(). (And starts loading the first track of the new playlist)
Try and get the hold of this in the examples

If you wonder all the logic, just check out the source, it has comments!

Credits

A lot of guidelines to realize a simple re-usable project like this have come mainly from:

Contributing

Contributing is always welcome, both via opening Issues, or compiling a Pull Request.

You can clone the repository and start working:

git clone git@github.com:colthreepv/angular-media-player.git
cd angular-media-player
?!?!?
profit!

To test the documentation system you need to:

npm install
# if you don't have bower installed globally
# sudo npm install bower -g
bower install
# if you don't have grunt installed globally
# sudo npm install grunt-cli -g
grunt docs
# keep grunt executing and open a browser on http://localhost:8181/

To create a new release:

npm install
# test before commit
bower install
npm test
grunt build
git commit -m "release X.Y.Z"
git tag X.Y.Z
git push && git push --tags

Release History