@@ -29,8 +29,10 @@ var IsPlainObject = require('../../utils/object/IsPlainObject');
2929 * @param {Phaser.Loader.LoaderPlugin } loader - A reference to the Loader that is responsible for this file.
3030 * @param {(string|Phaser.Types.Loader.FileTypes.VideoFileConfig) } key - The key to use for this file, or a file configuration object.
3131 * @param {any } [urlConfig] - The absolute or relative URL to load this file from in a config object.
32+ * @param {string } [loadEvent] - The load event to listen for when _not_ loading as a blob. Either 'loadeddata', 'canplay' or 'canplaythrough'.
33+ * @param {boolean } [asBlob] - Load the video as a data blob, or via the Video element?
34+ * @param {boolean } [noAudio] - Does the video have an audio track? If not you can enable auto-playing on it.
3235 * @param {Phaser.Types.Loader.XHRSettingsObject } [xhrSettings] - Extra XHR Settings specifically for this file.
33- * @param {AudioContext } [audioContext] - The AudioContext this file will use to process itself.
3436 */
3537var VideoFile = new Class ( {
3638
@@ -45,6 +47,11 @@ var VideoFile = new Class({
4547 if ( asBlob === undefined ) { asBlob = false ; }
4648 if ( noAudio === undefined ) { noAudio = false ; }
4749
50+ if ( loadEvent !== 'loadeddata' && loadEvent !== 'canplay' && loadEvent !== 'canplaythrough' )
51+ {
52+ loadEvent = 'loadeddata' ;
53+ }
54+
4855 var fileConfig = {
4956 type : 'video' ,
5057 cache : loader . cacheManager . video ,
@@ -60,7 +67,8 @@ var VideoFile = new Class({
6067 }
6168 } ;
6269
63- // console.log(fileConfig);
70+ this . onLoadCallback = this . onVideoLoadHandler . bind ( this ) ;
71+ this . onErrorCallback = this . onVideoErrorHandler . bind ( this ) ;
6472
6573 File . call ( this , loader , fileConfig ) ;
6674 } ,
@@ -69,13 +77,11 @@ var VideoFile = new Class({
6977 * Called automatically by Loader.nextFile.
7078 * This method controls what extra work this File does with its loaded data.
7179 *
72- * @method Phaser.Loader.FileTypes.BinaryFile #onProcess
73- * @since 3.7 .0
80+ * @method Phaser.Loader.FileTypes.VideoFile #onProcess
81+ * @since 3.20 .0
7482 */
7583 onProcess : function ( )
7684 {
77- // console.log('Video.onProcess', this.config.asBlob);
78-
7985 this . state = CONST . FILE_PROCESSING ;
8086
8187 if ( ! this . config . asBlob )
@@ -85,154 +91,134 @@ var VideoFile = new Class({
8591 return ;
8692 }
8793
88- var video = document . createElement ( 'video' ) ;
89-
90- video . controls = false ;
91- video . canplay = true ;
92-
93- video . setAttribute ( 'autoplay' , 'autoplay' ) ;
94- video . setAttribute ( 'playsinline' , 'playsinline' ) ;
94+ // Load Video as blob
9595
96- if ( this . config . noAudio )
97- {
98- video . muted = true ;
99- }
96+ var video = this . createVideoElement ( ) ;
10097
10198 this . data = video ;
10299
103100 var _this = this ;
104101
105102 this . data . onloadeddata = function ( )
106103 {
107- // console.log('data.onloadeddata');
108-
109104 File . revokeObjectURL ( _this . data ) ;
110105
111106 _this . onProcessComplete ( ) ;
112107 } ;
113108
114109 this . data . onerror = function ( )
115110 {
116- // console.log('data.onerror');
117-
118111 File . revokeObjectURL ( _this . data ) ;
119112
120113 _this . onProcessError ( ) ;
121114 } ;
122115
123- // console.log('onProcess createURL');
116+ File . createObjectURL ( video , this . xhrLoader . response , '' ) ;
117+
118+ video . load ( ) ;
119+ } ,
120+
121+ /**
122+ * Creates a Video Element within the DOM.
123+ *
124+ * @method Phaser.Loader.FileTypes.VideoFile#createVideoElement
125+ * @private
126+ * @since 3.20.0
127+ *
128+ * @return {HTMLVideoElement } The newly created Video element.
129+ */
130+ createVideoElement : function ( )
131+ {
132+ var video = document . createElement ( 'video' ) ;
133+
134+ video . controls = false ;
135+ video . crossOrigin = this . loader . crossOrigin ;
136+
137+ if ( this . config . noAudio )
138+ {
139+ video . muted = true ;
140+ video . defaultMuted = true ;
141+
142+ video . setAttribute ( 'autoplay' , 'autoplay' ) ;
143+ }
144+
145+ video . setAttribute ( 'playsinline' , 'playsinline' ) ;
146+ video . setAttribute ( 'preload' , 'auto' ) ;
124147
125- File . createObjectURL ( this . data , this . xhrLoader . response , '' ) ;
148+ return video ;
126149 } ,
127150
128151 /**
129- * Called when the file finishes loading, is sent a DOM ProgressEvent .
152+ * Internal load event callback .
130153 *
131- * @method Phaser.Loader.File#onLoad
132- * @since 3.0.0
154+ * @method Phaser.Loader.FileTypes.VideoFile#onVideoLoadHandler
155+ * @private
156+ * @since 3.20.0
133157 *
134- * @param {XMLHttpRequest } xhr - The XMLHttpRequest that caused this onload event.
135158 * @param {ProgressEvent } event - The DOM ProgressEvent that resulted from this load.
136- onLoadVideo: function (event)
159+ */
160+ onVideoLoadHandler : function ( event )
137161 {
138- console.log('onLoadVideo');
139- console.log(event);
140- console.log(this);
141-
142162 var video = event . target ;
143163
144- video.removeEventListener(this.config.loadEvent, this.onLoadVideo, true);
164+ video . removeEventListener ( this . config . loadEvent , this . onLoadCallback , true ) ;
165+ video . removeEventListener ( 'error' , this . onErrorCallback , true ) ;
145166
146167 this . data = video ;
147168
148169 this . resetXHR ( ) ;
149170
150171 this . loader . nextFile ( this , true ) ;
151172 } ,
173+
174+ /**
175+ * Internal load error event callback.
176+ *
177+ * @method Phaser.Loader.FileTypes.VideoFile#onVideoErrorHandler
178+ * @private
179+ * @since 3.20.0
180+ *
181+ * @param {ProgressEvent } event - The DOM ProgressEvent that resulted from this load.
152182 */
183+ onVideoErrorHandler : function ( event )
184+ {
185+ var video = event . target ;
186+
187+ if ( video )
188+ {
189+ video . removeEventListener ( this . config . loadEvent , this . onLoadCallback , true ) ;
190+ video . removeEventListener ( 'error' , this . onErrorCallback , true ) ;
191+ }
192+
193+ this . resetXHR ( ) ;
194+
195+ this . loader . nextFile ( this , false ) ;
196+ } ,
153197
154198 /**
155199 * Called by the Loader, starts the actual file downloading.
156200 * During the load the methods onLoad, onError and onProgress are called, based on the XHR events.
157201 * You shouldn't normally call this method directly, it's meant to be invoked by the Loader.
158202 *
159- * @method Phaser.Loader.FileTypes.HTML5AudioFile #load
160- * @since 3.0 .0
203+ * @method Phaser.Loader.FileTypes.VideoFile #load
204+ * @since 3.20 .0
161205 */
162206 load : function ( )
163207 {
164208 var loadEvent = this . config . loadEvent ;
165- var asBlob = this . config . asBlob ;
166- var noAudio = this . config . noAudio ;
167209
168- if ( asBlob )
210+ if ( this . config . asBlob )
169211 {
170- // console.log('Passing load over to File.load');
171-
172212 File . prototype . load . call ( this ) ;
173213 }
174214 else
175215 {
176- console . log ( 'Loading as Video tag' ) ;
177-
178216 this . percentComplete = 0 ;
179217
180- var video = document . createElement ( 'video' ) ;
181-
182- video . controls = false ;
183- video . crossOrigin = this . loader . crossOrigin ;
184-
185- if ( noAudio )
186- {
187- video . muted = true ;
188- video . defaultMuted = true ;
189-
190- video . setAttribute ( 'autoplay' , 'autoplay' ) ;
191- }
218+ var video = this . createVideoElement ( ) ;
192219
193- video . setAttribute ( 'playsinline' , 'playsinline' ) ;
194- video . setAttribute ( 'preload' , 'auto' ) ;
195-
196- var _this = this ;
197-
198- this . onVideoLoadHandler = function ( event )
199- {
200- console . log ( 'onVideoLoadHandler' ) ;
201- console . log ( event ) ;
202-
203- var video = event . target ;
204-
205- video . removeEventListener ( _this . config . loadEvent , _this . onVideoLoadHandler , true ) ;
206-
207- _this . data = video ;
208-
209- _this . resetXHR ( ) ;
210-
211- _this . loader . nextFile ( _this , true ) ;
212- } ;
213-
214- video . addEventListener ( loadEvent , this . onVideoLoadHandler , true ) ;
215-
216- video . addEventListener ( 'error' , function ( e )
217- {
218- console . log ( 'Load Error' ) ;
219- console . log ( e ) ;
220- } , true ) ;
221-
222- video . addEventListener ( 'loadstart' , function ( e )
223- {
224- console . log ( 'Load Start' ) ;
225- } , true ) ;
226-
227- video . addEventListener ( 'loadedmetadata' , function ( e )
228- {
229- console . log ( 'Loaded Meta Data' ) ;
230- } , true ) ;
231-
232- video . addEventListener ( 'emptied' , function ( e )
233- {
234- console . log ( 'Load Emptied' ) ;
235- } , true ) ;
220+ video . addEventListener ( loadEvent , this . onLoadCallback , true ) ;
221+ video . addEventListener ( 'error' , this . onErrorCallback , true ) ;
236222
237223 video . src = GetURL ( this , this . loader . baseURL ) ;
238224
@@ -258,8 +244,6 @@ VideoFile.create = function (loader, key, urls, loadEvent, asBlob, noAudio, xhrS
258244
259245 var urlConfig = VideoFile . getVideoURL ( game , urls ) ;
260246
261- // console.log(urlConfig);
262-
263247 if ( urlConfig )
264248 {
265249 return new VideoFile ( loader , key , urlConfig , loadEvent , asBlob , noAudio , xhrSettings ) ;
@@ -299,14 +283,14 @@ VideoFile.getVideoURL = function (game, urls)
299283} ;
300284
301285/**
302- * Adds an Audio or HTML5Audio file, or array of audio files, to the current load queue.
286+ * Adds a Video file, or array of video files, to the current load queue.
303287 *
304288 * You can call this method from within your Scene's `preload`, along with any other files you wish to load:
305289 *
306290 * ```javascript
307291 * function preload ()
308292 * {
309- * this.load.audio('title ', [ 'music/Title.ogg ', 'music/Title.mp3 ', 'music/Title.m4a ' ]);
293+ * this.load.video('intro ', [ 'video/level1.mp4 ', 'video/level1.webm ', 'video/level1.mov ' ]);
310294 * }
311295 * ```
312296 *
@@ -318,40 +302,45 @@ VideoFile.getVideoURL = function (game, urls)
318302 * Scene's `create` method is called you are guaranteed that all of those assets are ready for use and have been
319303 * loaded.
320304 *
321- * The key must be a unique String. It is used to add the file to the global Audio Cache upon a successful load.
322- * The key should be unique both in terms of files being loaded and files already present in the Audio Cache.
305+ * The key must be a unique String. It is used to add the file to the global Video Cache upon a successful load.
306+ * The key should be unique both in terms of files being loaded and files already present in the Video Cache.
323307 * Loading a file using a key that is already taken will result in a warning. If you wish to replace an existing file
324- * then remove it from the Audio Cache first, before loading a new one.
325- *
308+ * then remove it from the Video Cache first, before loading a new one.
309+ *
326310 * Instead of passing arguments you can pass a configuration object, such as:
327311 *
328312 * ```javascript
329- * this.load.audio({
330- * key: 'title',
331- * url: [ 'music/Title.ogg', 'music/Title.mp3', 'music/Title.m4a' ]
313+ * this.load.video({
314+ * key: 'intro',
315+ * url: [ 'video/level1.mp4', 'video/level1.webm', 'video/level1.mov' ],
316+ * asBlob: false,
317+ * noAudio: true
332318 * });
333319 * ```
334320 *
335321 * See the documentation for `Phaser.Types.Loader.FileTypes.VideoFileConfig` for more details.
336322 *
337323 * The URLs can be relative or absolute. If the URLs are relative the `Loader.baseURL` and `Loader.path` values will be prepended to them.
338324 *
339- * Due to different browsers supporting different audio file types you should usually provide your audio files in a variety of formats.
340- * ogg, mp3 and m4a are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on
341- * browser support.
342- *
343- * If audio has been disabled in your game, either via the game config, or lack of support from the device, then no audio will be loaded.
325+ * Due to different browsers supporting different video file types you should usually provide your video files in a variety of formats.
326+ * mp4, mov and webm are the most common. If you provide an array of URLs then the Loader will determine which _one_ file to load based on
327+ * browser support, starting with the first in the array and progressing to the end.
328+ *
329+ * Unlike most asset-types, videos do not _need_ to be preloaded. You can create a Video Game Object and then call its `loadURL` method,
330+ * to load a video at run-time, rather than in advance.
344331 *
345- * Note: The ability to load this type of file will only be available if the Audio File type has been built into Phaser.
332+ * Note: The ability to load this type of file will only be available if the Video File type has been built into Phaser.
346333 * It is available in the default build but can be excluded from custom builds.
347334 *
348335 * @method Phaser.Loader.LoaderPlugin#video
349336 * @fires Phaser.Loader.LoaderPlugin#addFileEvent
350337 * @since 3.20.0
351338 *
352339 * @param {(string|Phaser.Types.Loader.FileTypes.VideoFileConfig|Phaser.Types.Loader.FileTypes.VideoFileConfig[]) } key - The key to use for this file, or a file configuration object, or array of them.
353- * @param {(string|string[]) } [urls] - The absolute or relative URL to load the audio files from.
354- * @param {any } [config] - An object containing an `instances` property for HTML5Audio. Defaults to 1.
340+ * @param {(string|string[]) } [urls] - The absolute or relative URL to load the video files from.
341+ * @param {string } [loadEvent='loadeddata'] - The load event to listen for when _not_ loading as a blob. Either `loadeddata`, `canplay` or `canplaythrough`.
342+ * @param {boolean } [asBlob=false] - Load the video as a data blob, or stream it via the Video element?
343+ * @param {boolean } [noAudio=false] - Does the video have an audio track? If not you can enable auto-playing on it.
355344 * @param {Phaser.Types.Loader.XHRSettingsObject } [xhrSettings] - An XHR Settings configuration object. Used in replacement of the Loaders default XHR Settings.
356345 *
357346 * @return {Phaser.Loader.LoaderPlugin } The Loader instance.
0 commit comments