148 lines
3.4 KiB
Haxe
148 lines
3.4 KiB
Haxe
package kha.js;
|
|
|
|
import js.Browser;
|
|
import js.html.ErrorEvent;
|
|
import js.html.Event;
|
|
import js.html.MediaError;
|
|
import js.html.VideoElement;
|
|
|
|
using StringTools;
|
|
|
|
class Video extends kha.Video {
|
|
public var element: VideoElement;
|
|
public var texture: Image;
|
|
|
|
var filenames: Array<String>;
|
|
var done: kha.Video->Void;
|
|
|
|
function new() {
|
|
super();
|
|
}
|
|
|
|
public static function fromElement(element: js.html.VideoElement): Video {
|
|
var video = new Video();
|
|
video.element = element;
|
|
if (SystemImpl.gl != null)
|
|
video.texture = Image.fromVideo(video);
|
|
return video;
|
|
}
|
|
|
|
public static function fromFile(filenames: Array<String>, done: kha.Video->Void): Void {
|
|
var video = new Video();
|
|
|
|
video.done = done;
|
|
|
|
video.element = cast Browser.document.createElement("video");
|
|
|
|
video.filenames = [];
|
|
for (filename in filenames) {
|
|
if (video.element.canPlayType("video/webm") != "" && filename.endsWith(".webm"))
|
|
video.filenames.push(filename);
|
|
#if !kha_debug_html5
|
|
if (video.element.canPlayType("video/mp4") != "" && filename.endsWith(".mp4"))
|
|
video.filenames.push(filename);
|
|
#end
|
|
}
|
|
|
|
video.element.addEventListener("error", video.errorListener, false);
|
|
video.element.addEventListener("canplaythrough", video.canPlayThroughListener, false);
|
|
|
|
video.element.preload = "auto";
|
|
video.element.src = video.filenames[0];
|
|
}
|
|
|
|
override public function width(): Int {
|
|
return element.videoWidth;
|
|
}
|
|
|
|
override public function height(): Int {
|
|
return element.videoHeight;
|
|
}
|
|
|
|
override public function play(loop: Bool = false): Void {
|
|
try {
|
|
element.loop = loop;
|
|
element.play();
|
|
}
|
|
catch (e:Dynamic) {
|
|
trace(e);
|
|
}
|
|
}
|
|
|
|
override public function pause(): Void {
|
|
try {
|
|
element.pause();
|
|
}
|
|
catch (e:Dynamic) {
|
|
trace(e);
|
|
}
|
|
}
|
|
|
|
override public function stop(): Void {
|
|
try {
|
|
element.pause();
|
|
element.currentTime = 0;
|
|
}
|
|
catch (e:Dynamic) {
|
|
trace(e);
|
|
}
|
|
}
|
|
|
|
override public function getCurrentPos(): Int {
|
|
return Math.ceil(element.currentTime * 1000); // Miliseconds
|
|
}
|
|
|
|
override function get_position(): Int {
|
|
return Math.ceil(element.currentTime * 1000);
|
|
}
|
|
|
|
override function set_position(value: Int): Int {
|
|
element.currentTime = value / 1000;
|
|
return value;
|
|
}
|
|
|
|
override public function getVolume(): Float {
|
|
return element.volume;
|
|
}
|
|
|
|
override public function setVolume(volume: Float): Void {
|
|
element.volume = volume;
|
|
}
|
|
|
|
override public function getLength(): Int {
|
|
if (Math.isFinite(element.duration)) {
|
|
return Math.floor(element.duration * 1000); // Miliseconds
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
function errorListener(eventInfo: ErrorEvent): Void {
|
|
if (element.error.code == MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED) {
|
|
for (i in 0...filenames.length - 1) {
|
|
if (element.src == filenames[i]) {
|
|
// try loading with next extension:
|
|
element.src = filenames[i + 1];
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
trace("Error loading " + element.src);
|
|
finishAsset();
|
|
}
|
|
|
|
function canPlayThroughListener(eventInfo: Event): Void {
|
|
finishAsset();
|
|
}
|
|
|
|
function finishAsset() {
|
|
element.removeEventListener("error", errorListener, false);
|
|
element.removeEventListener("canplaythrough", canPlayThroughListener, false);
|
|
if (SystemImpl.gl != null)
|
|
texture = Image.fromVideo(this);
|
|
done(this);
|
|
}
|
|
}
|