Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow preload of Dash media without a video element #2274

Merged
merged 37 commits into from
Mar 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c895353
First attempt at media preloading, add PreBufferSink, refactor Source…
robertbryer Aug 9, 2017
7f6f23b
Remove/update other references to SourceBufferController
robertbryer Aug 9, 2017
308cdc9
Don't check element size when we don't have a videoModel
robertbryer Sep 11, 2017
7bef314
WIP on unit tests; pair init fragments in pre-buffer, guarantee appen…
robertbryer Sep 27, 2017
5b1a5c6
Fix buffering issue, make more unit tests work
robertbryer Oct 2, 2017
ba00323
Don't use lack of videoModel as a proxy for lack of an element
robertbryer Oct 12, 2017
1a28d08
Fire buffer loaded events only when loaded into mediasource buffer
robertbryer Oct 12, 2017
d90acf4
Make discharge accept null argument for all time
robertbryer Oct 12, 2017
adc1b55
Replace the currentWorkingTime thingy
robertbryer Oct 13, 2017
55fa4f9
Add preload function to api to activate preloading
robertbryer Oct 16, 2017
36d0fa4
Make the mediasource buffers first, then start discharging, because s…
robertbryer Oct 20, 2017
5c11ce1
Try to help IE11 remove source buffers
robertbryer Oct 23, 2017
b0010bf
Fix merge errors, fix unit test styling errors
robertbryer Nov 3, 2017
678a3cc
Fix merge errors, fix unit test styling errors
robertbryer Nov 3, 2017
8a04433
Timestamp offset storage not needed
robertbryer Nov 7, 2017
20e5d5e
More test cleanup
robertbryer Nov 7, 2017
e6cbd66
Fix path capitalisation
robertbryer Nov 7, 2017
c8ef90c
Bad merge, not preloading
robertbryer Nov 14, 2017
84d8980
Don't start preloading content if there's no video element
robertbryer Nov 14, 2017
8ce592f
Fix issue where preloading to the end of media wouldn't end it, repla…
robertbryer Jan 5, 2018
948d0b2
Fix rebase issues
robertbryer Feb 13, 2018
78106f8
Fix rebase issues
robertbryer Feb 13, 2018
96ac40d
Remove some stray sourceBufferController references
robertbryer Feb 13, 2018
1c5eed6
Fix preload discharge
robertbryer Feb 13, 2018
de07385
Move interface definition, clean up documentation
robertbryer Feb 14, 2018
5464991
Merge branch 'development' into preload
robertbryer Feb 15, 2018
85e0057
Fixup style
robertbryer Feb 15, 2018
486c210
Stop losing all the buffer from fragment model on sync
robertbryer Feb 21, 2018
e9a9888
Fix issue where init segments get lost when no corresponding media se…
robertbryer Feb 23, 2018
4468b8c
Merge branch 'development' into preload
robertbryer Feb 23, 2018
4686bc6
Fix jump-gaps
robertbryer Feb 23, 2018
23b7c8a
Merge branch 'development' into preload
robertbryer Mar 2, 2018
7ca03f1
Fix track switching merge
robertbryer Mar 2, 2018
153d42d
And fix the switch at end of buffering case
robertbryer Mar 2, 2018
06de370
Fix lint
robertbryer Mar 2, 2018
3555c4a
Add preload feature sample
jeoliva Mar 5, 2018
a2fddf5
Add preload method to type definitions
jeoliva Mar 5, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ declare namespace dashjs {
codec: string | null;
contentProtection: any | null;
}

export interface MediaPlayerClass {
initialize(view?: HTMLElement, source?: string, autoPlay?: boolean): void;
on(type: AstInFutureEvent['type'], listener: (e: AstInFutureEvent) => void, scope?: object): void;
Expand Down Expand Up @@ -202,6 +202,7 @@ declare namespace dashjs {
getJumpGaps(): boolean;
setSmallGapLimit(value: number): void;
getSmallGapLimit(): number;
preload(): void;
reset(): void;
}

Expand Down
62 changes: 62 additions & 0 deletions samples/getting-started-basic-embed/pre-load-video.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="utf-8" />
<title>Preload Video example</title>

<script src="../../dist/dash.all.debug.js"></script>
<!--dash.all.min.js should be used in production over dash.all.debug.js
Debug files are not compressed or obfuscated making the file size much larger compared with dash.all.min.js-->
<!--<script src="../../dist/dash.all.min.js"></script>-->

<script>
var video,
player;

function init() {
var url = "https://dash.akamaized.net/envivio/EnvivioDash3/manifest.mpd";

player = dashjs.MediaPlayer().create();
player.initialize(null, url, true);
player.preload();
}

function attachVideoPlayer() {
var videoContainer = document.getElementById('videoContainer');
if (!video) {
video = document.createElement('video');
video.controls = true;
videoContainer.appendChild(video);
}

player.attachView(video);
}
</script>

<style>
video {
width: 640px;
height: 360px;
}
</style>
</head>

<body>
<div>
This sample shows how to use preload feature of dash.js. In this sample, streaming is initialized and dash.js starts downloading stream segments as soon as the page is loaded. Right when the user clicks "Attach View" the video element is created,
attached to the already initialized dash.js MediaPlayer and then playback starts.
</div>
<div>
<button onclick="attachVideoPlayer()">Attach View</button>
</div>
<div id="videoContainer">
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
init();
});
</script>
</body>

</html>
1 change: 1 addition & 0 deletions samples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<tr><td style="width:80px"></td><td><a href="getting-started-basic-embed/auto-load-single-video-with-reference.html">auto-load-single-video-with-reference.html</a> - this example shows how to auto-embed the player while still obtaining a reference to the MediaPlayer instance. This is useful for calling its public API, which the example illustrates by tracing out the players buffer length. </td></tr>
<tr><td style="width:80px"></td><td><a href="getting-started-basic-embed/auto-load-multi-video.html">auto-load-multi-video.html</a> - this example shows how to auto-embed multiple instances of dash.js players in a page. To make it more difficult, one of the available video elements specifies a non-DASH source. </td></tr>
<tr><td style="width:80px"></td><td><a href="getting-started-basic-embed/manual-load-single-video.html">manual-load-single-video.html</a> - for the fullest embed control, go back to basics. This example shows how to instantiate and initialize a dash.js player without using any of the Dash.create() methods. Consider this the baseline embed example. </td></tr>
<tr><td style="width:80px"></td><td><a href="getting-started-basic-embed/pre-load-video.html">pre-load-video.html</a> - this examples shows how to use preload feature of dash.js, which allows to initialize streaming and starts downloading the content before the player is attached to a video element</td></tr>

<tr><td colspan="2">/live-streaming</td></tr>
<tr><td style="width:80px"></td><td><a href="live-streaming/live-delay-comparison-custom-manifest.html">live-delay-comparison-custom-manifest.html</a> - example showing how to use the two MediaPlayer APIS which control live delay: setLiveDelay and setLiveDelayFragmentCount.</td></tr>
Expand Down
1 change: 0 additions & 1 deletion src/core/events/CoreEvents.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ class CoreEvents extends EventsBase {
this.SEGMENTS_LOADED = 'segmentsLoaded';
this.SERVICE_LOCATION_BLACKLIST_ADD = 'serviceLocationBlacklistAdd';
this.SERVICE_LOCATION_BLACKLIST_CHANGED = 'serviceLocationBlacklistChanged';
this.SOURCEBUFFER_APPEND_COMPLETED = 'sourceBufferAppendCompleted';
this.SOURCEBUFFER_REMOVE_COMPLETED = 'sourceBufferRemoveCompleted';
this.STREAMS_COMPOSED = 'streamsComposed';
this.STREAM_BUFFERING_COMPLETED = 'streamBufferingCompleted';
Expand Down
1 change: 1 addition & 0 deletions src/dash/DashHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ function DashHandler(config) {
request.index = segment.availabilityIdx;
request.mediaInfo = streamProcessor.getMediaInfo();
request.adaptationIndex = representation.adaptation.index;
request.representationId = representation.id;

if (setRequestUrl(request, url, representation)) {
return request;
Expand Down
59 changes: 59 additions & 0 deletions src/streaming/FragmentSink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* The copyright in this software is being made available under the BSD License,
* included below. This software may be subject to other third party and contributor
* rights, including patent rights, and no such rights are granted under this license.
*
* Copyright (c) 2013, Dash Industry Forum.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Neither the name of Dash Industry Forum nor the names of its
* contributors may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS AS IS AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

/**
* The an end place to put fragments after they have been fetched.
* @interface FragmentSink
*/
/**
* Append a chunk to the internal buffer. You should assume that the effects of this are asynchronous.
* @function FragmentSink#append
* @param {Object} chunk A loaded chunk like that generated by the FragmentController
*/
/**
* Remove data from within the specified time ranges.
* @function FragmentSink#remove
* @param {?Number} start The beginning of the range that should be removed from the sink's internal buffer. If NaN, it is regarded as unbounded.
* @param {?Number} end The end of the range that should be removed from the sink's internal buffer. If NaN, it is regarded as unbounded.
*/
/**
* Abort an append operation currently ongoing.
* @function FragmentSink#abort
*/
/**
* @function FragmentSink#getAllBufferRanges
* @returns {Array} A TimeRanges-like object representing all the buffer ranges that are present in the sink.
*/
/**
* Remove all the data in the sink's internal buffer.
* @function FragmentSink#reset
*/