Skip to content

Commit

Permalink
Merge pull request #588 from AkamaiDASH/master
Browse files Browse the repository at this point in the history
v1.4 Release
  • Loading branch information
Dan Sparacio authored and Dan Sparacio committed Jun 12, 2015
2 parents 8c4a545 + 78c3d45 commit b272b18
Show file tree
Hide file tree
Showing 163 changed files with 13,797 additions and 5,531 deletions.
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ language: node_js
node_js:
- "0.11"
- "0.10"
script: cd build && npm install && npm test
before_install: cd build && npm install -g grunt-cli
install: npm install
44 changes: 44 additions & 0 deletions AUTHORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Dash.js Authors List
#####Please add entries to the bottom of the list in the following format
* @GitHub UserName (Required) [Name and/or Organization] (Optional)

#Authors
* @nweber [Digital Primates]
* @jefftapper [Jeff Tapper, Digital Primates]
* @KozhinM [Mikail Kozhin, Microsoft Open Technologies]
* @kirkshoop [Kirk Shoop, Microsoft Open Technologies]
* @wilaw [Will Law, Akamai Technologies]
* @AkamaiDASH [Dan Sparacio, Akamai Technologies]
* @dsilhavy [Daniel Silhavy, Fraunhofer Fokus]
* @greg80303 [Greg Rutz, CableLabs]
* @heff [Steve Hefferman, Brightcove]
* @Tomjohnson916 [Tom Johnson, Brightcove]
* @jeroenwiljering [Jeroen Wijering, JWPlayer]
* @bbcrddave [David Evans, BBC R&D]
* @bbert [Bertrand Berthelot, Orange]
* @vigneshvg [Vignesh Venkatasubramanian, Google]
* @nicosang [Nicolas Angot, Orange]
* @PriyadarshiniV
* @senthil-codr [Senthil]
* @dweremeichik [Dylan Weremeichik]
* @aleal-envivio
* @mconlin
* @umavinoth
* @lbonn
* @mdale [Michael Dale, Kaltura]
* @sgrebnov [Sergey Grebnov, Microsoft Open Technologies]
* @wesleytodd [Wes Todd, Vubeology]
* @colde [Loke Dupont, Xstream]
* @rgardler [Ross Gardler, Microsoft Open Technologies]
* @squapp
* @xiaomings
* @rcollins112 [Rich Collins, Wowza]
* @timothy003 [Timothy Liang]
* @JaapHaitsma
* @72lions [Thodoris Tsiridis, 72lions]
* @TobbeMobiTV [Torbjörn Einarsson, MobiTV]
* @mstorsjo [Martin Storsjö]
* @Hyddan [Daniel Hedenius]
* @qjia7
* @waqarz
* @WMSPanel [WMSPanel Team]
54 changes: 41 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,59 @@
# dash.js

<img src="https://cloud.githubusercontent.com/assets/2762250/7824984/985c3e76-03bc-11e5-807b-1402bde4fe56.png" width="400">

JSHint and Jasmine status: [![JSHint and Jasmine](http://img.shields.io/travis/Dash-Industry-Forum/dash.js/development.svg?style=flat-square)](https://travis-ci.org/Dash-Industry-Forum/dash.js)

A reference client implementation for the playback of MPEG DASH via JavaScript and compliant browsers. Learn more about DASH IF Reference Client.
A reference client implementation for the playback of MPEG DASH via JavaScript and compliant browsers. Learn more about DASH IF Reference Client on our [wiki](https://github.com/Dash-Industry-Forum/dash.js/wiki).

If your intent is to use the player code without contributing back to this project, then use the MASTER branch which holds the approved and stable public releases.

If your goal is to improve or extend the code and contribute back to this project, then you should make your changes in, and submit a pull request against, the DEVELOPMENT branch. Read through our wiki section on https://github.com/Dash-Industry-Forum/dash.js/wiki/How-to-Contribute for a walk-through of the contribution process.

All new work should be in the development branch. Master is now reserved to tag builds.
All new work should be in the development branch. Master is now reserved for tagged builds.

## Quick Start for Users
If you just want a DASH player to use and don't need to see the code or commit to this project, then follow the instructions below. If you are a developer and want to work with this code base, then skip down to the "Quick Start for Developers" section.

Put the following code in your web page
```
<script src="http://cdn.dashjs.org/latest/dash.all.js"></script>
...
<body onLoad="Dash.createAll()">
<div>
<video class="dashjs-player" autoplay preload="none" controls="true">
<source src="http://dash.edgesuite.net/envivio/dashpr/clear/Manifest.mpd" type="application/dash+xml"/>
</video>
</div>
</body>
```
Then place your page under a web server (do not try to run from the file system) and load it via http in a MSE-enabled browser. The video will start automatically. Switch out the manifest URL to your own manifest once you have everything working. If you prefer to use the latest code from this project (versus the last tagged release) then download dash.all.js file from the development/dist folder, mount it on a web server and change your script tag to refer to it.

## Quick Start
View the /samples folder for many other examples of embedding and using the player. For help, join our [email list](https://groups.google.com/d/forum/dashjs) and read our [wiki](https://github.com/Dash-Industry-Forum/dash.js/wiki) .

Download 'master' or latest tagged release, extract and open main folder dash.js/index.html in your web browser to view the main test file.

## Quick Start for Developers

### Reference Player
1. Download 'master' or latest tagged release.
2. Extract dash.js and move the entire folder to localhost (or run any http server instance such as python's SimpleHTTPServer at the root of the dash.js folder).
3. Open samples/dash-if-reference-player/index.html in your MSE capable web browser.

### Install Dependencies
1. [install nodejs](http://nodejs.org/)
2. [install grunt](http://gruntjs.com/getting-started)
* npm install -g grunt-cli
3. [install grunt-template-jasmine-istanbul](https://github.com/maenu/grunt-template-jasmine-istanbul)
* npm install grunt-template-jasmine-istanbul --save-dev
4. install some other dependencies:
* npm install grunt-contrib-connect grunt-contrib-watch grunt-contrib-jshint grunt-contrib-uglify grunt-jsdoc-plugin grunt-jsdoc

### Build / Run tests:
```
grunt --config Gruntfile.js --force
```
### Build / Run tests
1. Change directories to the build folder
* cd build/
2. Install all Node Modules defined in package.json
* npm install
3. Run all the GruntFile.js task (Complete Build and Test)
* grunt
4. You can also target individual tasks:
* grunt uglify
* grunt jsdoc
* grunt jshint

## Getting Started
Create a video element somewhere in your html. For our purposes, make sure to set the controls property to true.
Expand Down Expand Up @@ -77,3 +104,4 @@ When it is all done, it should look similar to this:
</body>
</html>
```

3 changes: 2 additions & 1 deletion build/Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ module.exports = function(grunt) {
template: require('grunt-template-jasmine-istanbul'),
templateOptions: {
coverage: './reports/coverage.json',
report: './reports/coverage'
report: './reports/coverage',
files: '../**/*'
},
junit: {
path: grunt.option('jsunit-path'),
Expand Down
6 changes: 4 additions & 2 deletions build/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{
"name": "dashjs",
"version": "1.3.0",
"readme": "../README.md",
"version": "1.4.0",
"devDependencies": {
"grunt": "~0.4.2",
"grunt-contrib-connect": "~0.7.1",
Expand All @@ -13,6 +12,9 @@
"grunt-template-jasmine-istanbul": "=0.3.0",
"jasmine-sinon": "~0.3.1"
},
"scripts": {
"test": "grunt"
},
"repository": {
"type": "git",
"url": "https://github.com/Dash-Industry-Forum/dash.js.git"
Expand Down
2 changes: 1 addition & 1 deletion build/test/js/dash/TimeLineConverterSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ describe("TimelineConverter", function () {
range = timelineConverter.calcSegmentAvailabilityRange(representation, isDynamic);

expect(range.start).toEqual(expectedValue);
expectedValue = 10;
expectedValue = 9;
expect(range.end).toEqual(expectedValue);
});
});
Expand Down
141 changes: 59 additions & 82 deletions build/test/js/streaming/AbrControllerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,103 +4,80 @@ describe("AbrController", function () {
abrCtrl = objectsHelper.getAbrController(),
testedType = "video",
defaultQuality = helper.getDefaultQuality(),
trackCtrl = objectsHelper.getTrackController(testedType),
onDataUpdateCompletedEventName = Dash.dependencies.RepresentationController.eventList.ENAME_DATA_UPDATE_COMPLETED,
onTopQualityIndexChangedEventName = MediaPlayer.dependencies.AbrController.eventList.ENAME_TOP_QUALITY_INDEX_CHANGED,
dummyAdaptation = window.Helpers.getMpdHelper().getAdaptationWithSegmentTemplate(testedType),
dummyRepresentation = window.Helpers.getVOHelper().getDummyRepresentation(testedType),
dummyMediaInfo = window.Helpers.getVOHelper().getDummyMediaInfo("video"),
streamInfo = {id: "id1"},
repsCount = dummyAdaptation.Representation_asArray.length;
trackCount = dummyMediaInfo.trackCount;

it("should have a handler for RepcresentationController.onDataUpdateCompleted event", function () {
expect(typeof(abrCtrl[onDataUpdateCompletedEventName])).toBe("function");
});

describe("when data update completed", function () {
var eventDelay = helper.getExecutionDelay();

beforeEach(function () {
jasmine.clock().install();

setTimeout(function(){
abrCtrl[onDataUpdateCompletedEventName]({sender: trackCtrl, data:{data: dummyAdaptation, currentRepresentation: dummyRepresentation}});
}, eventDelay);
});
dummyMediaInfo.streamInfo = streamInfo;

afterEach(function(){
jasmine.clock().uninstall();
});

it("should update top quality index", function () {
var dummyObserver = {},
expectedTopQuality = repsCount - 1,
actualTopQuality = NaN;

dummyObserver[onTopQualityIndexChangedEventName] = function(e){
actualTopQuality = e.data.maxIndex;
};
it("should update top quality index", function () {
var expectedTopQuality = trackCount - 1,
actualTopQuality;

abrCtrl.subscribe(onTopQualityIndexChangedEventName, dummyObserver);
actualTopQuality = abrCtrl.updateTopQualityIndex(dummyMediaInfo);

jasmine.clock().tick(eventDelay + 1);
expect(actualTopQuality).toEqual(expectedTopQuality);
});

expect(actualTopQuality).toEqual(expectedTopQuality);
});
it("should set a quality in a range between zero and a top quality index", function () {
var testQuality = 1,
newQuality;

it("should set a quality in a range between zero and a top quality index", function () {
jasmine.clock().tick(eventDelay + 1);
abrCtrl.setPlaybackQuality(testedType, streamInfo, testQuality);
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(testQuality);
});

var testQuality = 1,
newQuality;
abrCtrl.setPlaybackQuality(testedType, streamInfo, testQuality);
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(testQuality);
});
it("should throw an exception when attempting to set not a number value for a quality", function () {
var testQuality = "a";
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
testQuality = null;
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
testQuality = 2.5;
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
testQuality = {};
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
});

it("should throw an exception when attempting to set not a number value for a quality", function () {
jasmine.clock().tick(eventDelay + 1);
it("should ignore an attempt to set a negative quality value", function () {
var negativeQuality = -1,
oldQuality = abrCtrl.getQualityFor(testedType, streamInfo),
newQuality;
abrCtrl.setPlaybackQuality(testedType, streamInfo, negativeQuality);
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(oldQuality);
});

var testQuality = "a";
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
testQuality = null;
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
testQuality = 2.5;
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
testQuality = {};
expect(abrCtrl.setPlaybackQuality.bind(abrCtrl, testedType, streamInfo, testQuality)).toThrow("argument is not an integer");
});
it("should ignore an attempt to set a quality greater than top quality index", function () {
var greaterThanTopQualityValue = trackCount,
oldQuality = abrCtrl.getQualityFor(testedType, streamInfo),
newQuality;
abrCtrl.setPlaybackQuality(testedType, streamInfo, greaterThanTopQualityValue);
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(oldQuality);
});

it("should ignore an attempt to set a negative quality value", function () {
jasmine.clock().tick(eventDelay + 1);
it("should restore a default quality value after reset", function () {
var newQuality,
testQuality = 1;
abrCtrl.setPlaybackQuality(testedType, streamInfo, testQuality);
abrCtrl.reset();
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(defaultQuality);
});

var negativeQuality = -1,
oldQuality = abrCtrl.getQualityFor(testedType, streamInfo),
newQuality;
abrCtrl.setPlaybackQuality(testedType, streamInfo, negativeQuality);
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(oldQuality);
});
it("should compose a list of available bitrates", function () {
var expectedBitrates = dummyMediaInfo.bitrateList,
actualBitrates = abrCtrl.getBitrateList(dummyMediaInfo),
item,
match;

it("should ignore an attempt to set a quality greater than top quality index", function () {
jasmine.clock().tick(eventDelay + 1);
match = expectedBitrates.filter(function(val, idx/*, arr*/) {
item = actualBitrates[idx];

var greaterThanTopQualityValue = repsCount,
oldQuality = abrCtrl.getQualityFor(testedType, streamInfo),
newQuality;
abrCtrl.setPlaybackQuality(testedType, streamInfo, greaterThanTopQualityValue);
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(oldQuality);
return (item && (item.qualityIndex === idx) && (item.bitrate === val) && (item.mediaType === dummyMediaInfo.type));
});

it("should restore a default quality value after reset", function () {
jasmine.clock().tick(eventDelay + 1);

var newQuality,
testQuality = 1;
abrCtrl.setPlaybackQuality(testedType, streamInfo, testQuality);
abrCtrl.reset();
newQuality = abrCtrl.getQualityFor(testedType, streamInfo);
expect(newQuality).toEqual(defaultQuality);
});
expect(match.length).toEqual(expectedBitrates.length);
});
});

0 comments on commit b272b18

Please sign in to comment.