aboutsummaryrefslogtreecommitdiffstats
path: root/src/client/Player.hx
diff options
context:
space:
mode:
Diffstat (limited to 'src/client/Player.hx')
-rw-r--r--src/client/Player.hx124
1 files changed, 118 insertions, 6 deletions
diff --git a/src/client/Player.hx b/src/client/Player.hx
index bc64053..f40c34c 100644
--- a/src/client/Player.hx
+++ b/src/client/Player.hx
@@ -10,7 +10,9 @@ import client.players.Streamable;
import client.players.Youtube;
import haxe.Http;
import haxe.Json;
+import js.html.Audio;
import js.html.Element;
+import js.html.InputElement;
class Player {
final main:Main;
@@ -25,13 +27,21 @@ class Player {
var isLoaded = false;
var skipSetTime = false;
var skipSetRate = false;
+ var streamable:Streamable;
+
+ final voiceOverInput:InputElement = cast ge("#voiceoverurl");
+ var audioTrack:Null<Audio>;
+ var isAudioTrackLoaded = false;
+ var needsVolumeReset = false;
+ final voiceOverVolume = 0.3;
public function new(main:Main):Void {
this.main = main;
youtube = new Youtube(main, this);
+ streamable = new Streamable(main, this);
players = [
youtube,
- new Streamable(main, this)
+ streamable
];
iframePlayer = new Iframe(main, this);
rawPlayer = new Raw(main, this);
@@ -97,19 +107,26 @@ class Player {
if (player != null) {
JsApi.fireVideoRemoveEvents(videoList.currentItem);
player.removeVideo();
+ removeExternalAudioTrack();
}
main.blinkTabWithTitle("*Video*");
}
player = newPlayer;
}
- public function getVideoData(data:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
- var player = players.find(player -> player.isSupportedLink(data.url));
+ public function getVideoData(req:VideoDataRequest, callback:(data:VideoData) -> Void):Void {
+ var player = players.find(player -> player.isSupportedLink(req.url));
player ??= rawPlayer;
- player.getVideoData(data, callback);
+ player.getVideoData(req, data -> {
+ final voiceOverTrack = voiceOverInput.value.trim();
+ data.voiceOverTrack = voiceOverTrack;
+ voiceOverInput.value = "";
+ callback(data);
+ });
}
public function isRawPlayerLink(url:String):Bool {
+ if (streamable.isSupportedLink(url)) return true;
return !players.exists(player -> player.isSupportedLink(url));
}
@@ -129,6 +146,7 @@ class Player {
isLoaded = false;
if (main.isVideoEnabled) {
player.loadVideo(item);
+ setExternalAudioTrack(item);
} else {
onCanBePlayed();
}
@@ -136,6 +154,42 @@ class Player {
ge("#currenttitle").textContent = item.title;
}
+ function setExternalAudioTrack(item:VideoItem):Void {
+ removeExternalAudioTrack();
+ final voiceOverTrack = item.voiceOverTrack ?? return;
+ if (voiceOverTrack.length == 0) return;
+ audioTrack = new Audio(voiceOverTrack);
+ if (!main.isAutoplayAllowed()) {
+ audioTrack.muted = true;
+ }
+ inline function cleanAudioEvents() {
+ audioTrack.oncanplay = null;
+ audioTrack.onerror = null;
+ }
+ audioTrack.oncanplay = () -> {
+ cleanAudioEvents();
+ isAudioTrackLoaded = true;
+ }
+ audioTrack.onerror = e -> {
+ trace(e);
+ cleanAudioEvents();
+ isAudioTrackLoaded = false;
+ audioTrack = null;
+ setVolume(1);
+ }
+ }
+
+ function removeExternalAudioTrack():Void {
+ isAudioTrackLoaded = false;
+ needsVolumeReset = false;
+ if (audioTrack == null) return;
+
+ audioTrack?.pause();
+ audioTrack.src = null;
+ audioTrack = null;
+ needsVolumeReset = true;
+ }
+
function setSupportedPlayer(url:String, isIframe:Bool):Void {
final currentPlayer = players.find(p -> p.isSupportedLink(url));
if (currentPlayer != null) setPlayer(currentPlayer);
@@ -171,6 +225,8 @@ class Player {
}
public function onPlay():Void {
+ audioTrack?.play();
+
if (!main.isLeader()) return;
main.send({
type: Play,
@@ -186,6 +242,8 @@ class Player {
}
public function onPause():Void {
+ audioTrack?.pause();
+
final item = videoList.currentItem ?? return;
// do not send pause if video is ended
if (getTime() >= item.duration - 0.01) return;
@@ -193,8 +251,10 @@ class Player {
if (player == rawPlayer && youtube.isSupportedLink(item.url)) {
if (getTime() >= item.duration - 1) return;
}
- final hasAutoPause = main.hasLeaderOnPauseRequest() && videoList.length > 0
- && getTime() > 1;
+ final hasAutoPause = main.hasLeaderOnPauseRequest()
+ && videoList.length > 0
+ && getTime() > 1
+ && isLoaded;
if (hasAutoPause && !main.hasLeader()) {
JsApi.once(SetLeader, event -> {
final name = event.setLeader.clientName;
@@ -220,6 +280,10 @@ class Player {
}
public function onSetTime():Void {
+ if (audioTrack != null) {
+ audioTrack.currentTime = getTime();
+ }
+
if (skipSetTime) {
skipSetTime = false;
return;
@@ -234,6 +298,9 @@ class Player {
}
public function onRateChange():Void {
+ if (audioTrack != null) {
+ audioTrack.playbackRate = getPlaybackRate();
+ }
if (skipSetRate) {
skipSetRate = false;
return;
@@ -410,6 +477,7 @@ class Player {
}
public function isVideoLoaded():Bool {
+ if (player == null) return false;
return player.isVideoLoaded();
}
@@ -418,6 +486,12 @@ class Player {
if (player == null) return;
if (!player.isVideoLoaded()) return;
player.play();
+ if (needsVolumeReset) setVolume(1);
+
+ if (audioTrack != null) {
+ setVolume(0.3);
+ audioTrack?.play();
+ }
}
public function pause():Void {
@@ -425,6 +499,8 @@ class Player {
if (player == null) return;
if (!player.isVideoLoaded()) return;
player.pause();
+
+ audioTrack?.pause();
}
public function getTime():Float {
@@ -439,6 +515,8 @@ class Player {
if (!player.isVideoLoaded()) return;
skipSetTime = isLocal;
player.setTime(time);
+
+ if (audioTrack != null) audioTrack.currentTime = time;
}
public function getPlaybackRate():Float {
@@ -453,6 +531,8 @@ class Player {
if (!player.isVideoLoaded()) return;
skipSetRate = isLocal;
player.setPlaybackRate(rate);
+
+ if (audioTrack != null) audioTrack.playbackRate = rate;
}
public function skipAd():Void {
@@ -484,4 +564,36 @@ class Player {
http.onError = msg -> trace(msg);
http.request();
}
+
+ public function isPaused():Bool {
+ if (player == null) return true;
+ if (!player.isVideoLoaded()) return true;
+ return player.isPaused();
+ }
+
+ public function getVolume():Float {
+ if (player == null) return 1;
+ if (!player.isVideoLoaded()) return 1;
+ return player.getVolume();
+ }
+
+ public function setVolume(volume:Float):Void {
+ if (player == null) return;
+ if (!player.isVideoLoaded()) return;
+ player.setVolume(volume);
+ }
+
+ public function unmute():Void {
+ if (player == null) return;
+ if (!player.isVideoLoaded()) return;
+ player.unmute();
+ if (audioTrack != null) audioTrack.muted = false;
+ if (audioTrack == null && almostEq(getVolume(), voiceOverVolume, 0.01)) {
+ setVolume(1);
+ }
+ }
+
+ function almostEq(a:Float, b:Float, diff:Float):Bool {
+ return a > b - diff && a < b + diff;
+ }
}
send patches to the email below
yukais@pinapelz.com
include the subject [PATCH repo_name]
pinapelz.com
homepage