Skip to content

Commit

Permalink
Flashback time per item, improve webm/webp support
Browse files Browse the repository at this point in the history
  • Loading branch information
RblSb committed Jan 1, 2024
1 parent 0d1fd0f commit c9b920c
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 71 deletions.
127 changes: 91 additions & 36 deletions build/server.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions res/client.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions src/Types.hx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,12 @@ typedef VideoItem = {
isIframe:Bool
}

typedef FlashbackItem = {
url:String,
duration:Float,
time:Float
}

typedef WsEvent = {
type:WsEventType,
?connected:{
Expand Down
4 changes: 3 additions & 1 deletion src/VideoList.hx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ class VideoList {
return items.length;
}

public inline function getCurrentItem():VideoItem {
public var currentItem(get, never):VideoItem;

inline function get_currentItem():Null<VideoItem> {
return items[pos];
}

Expand Down
6 changes: 4 additions & 2 deletions src/client/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -720,7 +720,8 @@ class Main {
});
}
for (emote in config.emotes) {
final tag = emote.image.endsWith("mp4") ? 'video autoplay="" loop="" muted=""' : "img";
final isVideoExt = emote.image.endsWith("mp4") || emote.image.endsWith("webm");
final tag = isVideoExt ? 'video autoplay="" loop="" muted=""' : "img";
filters.push({
regex: new EReg("(^| )" + escapeRegExp(emote.name) + "(?!\\S)", "g"),
replace: '$1<$tag class="channel-emote" src="${emote.image}" title="${emote.name}"/>'
Expand All @@ -739,7 +740,8 @@ class Main {
}
smilesList.textContent = "";
for (emote in config.emotes) {
final tag = emote.image.endsWith("mp4") ? "video" : "img";
final isVideoExt = emote.image.endsWith("mp4") || emote.image.endsWith("webm");
final tag = isVideoExt ? "video" : "img";
final el = document.createElement(tag);
el.className = "smile-preview";
el.dataset.src = emote.image;
Expand Down
19 changes: 9 additions & 10 deletions src/client/Player.hx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ class Player {
function setPlayer(newPlayer:IPlayer):Void {
if (player != newPlayer) {
if (player != null) {
JsApi.fireVideoRemoveEvents(videoList.getCurrentItem());
JsApi.fireVideoRemoveEvents(videoList.currentItem);
player.removeVideo();
}
main.blinkTabWithTitle("*Video*");
Expand Down Expand Up @@ -139,7 +139,7 @@ class Player {
public function changeVideoSrc(src:String):Void {
if (!main.isVideoEnabled) return;
if (player == null) return;
final item = videoList.getCurrentItem() ?? return;
final item = videoList.currentItem ?? return;
player.loadVideo({
url: src,
title: item.title,
Expand All @@ -152,7 +152,7 @@ class Player {
}

public function removeVideo():Void {
JsApi.fireVideoRemoveEvents(videoList.getCurrentItem());
JsApi.fireVideoRemoveEvents(videoList.currentItem);
player.removeVideo();
ge("#currenttitle").textContent = Lang.get("nothingPlaying");
setPauseIndicator(true);
Expand Down Expand Up @@ -278,7 +278,7 @@ class Player {
var index = videoList.findIndex(item -> item.url == url);
if (index == -1) return;

final isCurrent = videoList.getCurrentItem().url == url;
final isCurrent = videoList.currentItem.url == url;
videoList.removeItem(index);
updateCounters();

Expand All @@ -301,7 +301,7 @@ class Player {
if (pos == -1) return;
removeActiveLabel(videoList.pos);
videoList.setPos(pos);
if (videoList.getCurrentItem().isTemp) removeElementItem(url);
if (videoList.currentItem.isTemp) removeElementItem(url);
videoList.skipItem();
updateCounters();
if (videoList.length == 0) return;
Expand Down Expand Up @@ -332,15 +332,14 @@ class Player {
}

public function setItems(list:Array<VideoItem>, ?pos:Int):Void {
final currentUrl = videoList.pos >= videoList.length ? "" : videoList.getCurrentItem()
.url;
final currentUrl = videoList.pos >= videoList.length ? "" : videoList.currentItem.url;
clearItems();
if (list.length == 0) return;
for (video in list) {
addVideoItem(video, true);
}
if (pos != null) videoList.setPos(pos);
if (currentUrl != videoList.getCurrentItem().url) setVideo(videoList.pos);
if (currentUrl != videoList.currentItem.url) setVideo(videoList.pos);
else addActiveLabel(videoList.pos);
}

Expand Down Expand Up @@ -401,7 +400,7 @@ class Player {

public function getDuration():Float {
if (videoList.pos >= videoList.length) return 0;
return videoList.getCurrentItem().duration;
return videoList.currentItem.duration;
}

public function isVideoLoaded():Bool {
Expand Down Expand Up @@ -451,7 +450,7 @@ class Player {
}

public function skipAd():Void {
final item = videoList.getCurrentItem() ?? return;
final item = videoList.currentItem ?? return;
if (!youtube.isSupportedLink(item.url)) return;
final id = youtube.extractVideoId(item.url);
final url = 'https://sponsor.ajay.app/api/skipSegments?videoID=$id';
Expand Down
7 changes: 5 additions & 2 deletions src/server/HttpServer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,16 @@ class HttpServer {
"css" => "text/css",
"json" => "application/json",
"png" => "image/png",
"jpg" => "image/jpg",
"jpg" => "image/jpeg",
"jpeg" => "image/jpeg",
"gif" => "image/gif",
"webp" => "image/webp",
"svg" => "image/svg+xml",
"ico" => "image/x-icon",
"wav" => "audio/wav",
"mp3" => "audio/mpeg",
"mp4" => "video/mp4",
"webm" => "video/webm",
"woff" => "application/font-woff",
"ttf" => "application/font-ttf",
"eot" => "application/vnd.ms-fontobject",
Expand Down Expand Up @@ -152,7 +155,7 @@ class HttpServer {
}

static function isMediaExtension(ext:String):Bool {
return ext == "mp4" || ext == "mp3" || ext == "wav";
return ext == "mp4" || ext == "webm" || ext == "mp3" || ext == "wav";
}

static final matchLang = ~/^[A-z]+/;
Expand Down
79 changes: 62 additions & 17 deletions src/server/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package server;

import Client.ClientData;
import Types.Config;
import Types.FlashbackItem;
import Types.Message;
import Types.Permission;
import Types.UserList;
import Types.VideoItem;
import Types.WsEvent;
import haxe.Json;
import haxe.Timer;
Expand Down Expand Up @@ -618,10 +620,13 @@ class Main {
if (!checkPermission(client, RemoveVideoPerm)) return;
if (videoList.length == 0) return;
final url = data.removeVideo.url;
var index = videoList.findIndex(item -> item.url == url);
final index = videoList.findIndex(item -> item.url == url);
if (index == -1) return;

final isCurrent = videoList.getCurrentItem().url == url;
final isCurrent = videoList.currentItem.url == url;
if (isCurrent && videoTimer.getTime() > FLASHBACK_DIST) {
saveFlashbackTime(videoList.currentItem);
}
videoList.removeItem(index);
if (isCurrent && videoList.length > 0) {
broadcast(data);
Expand All @@ -638,7 +643,7 @@ class Main {
if (videoList.length == 0) return;
if (!client.isLeader) return;
if (Math.abs(data.pause.time - videoTimer.getTime()) > FLASHBACK_DIST) {
saveFlashbackTime();
saveFlashbackTime(videoList.currentItem);
}
videoTimer.setTime(data.pause.time);
videoTimer.pause();
Expand All @@ -651,7 +656,7 @@ class Main {
if (videoList.length == 0) return;
if (!client.isLeader) return;
if (Math.abs(data.play.time - videoTimer.getTime()) > FLASHBACK_DIST) {
saveFlashbackTime();
saveFlashbackTime(videoList.currentItem);
}
videoTimer.setTime(data.play.time);
videoTimer.play();
Expand All @@ -662,11 +667,11 @@ class Main {

case GetTime:
if (videoList.length == 0) return;
final maxTime = videoList.getCurrentItem().duration - 0.01;
final maxTime = videoList.currentItem.duration - 0.01;
if (videoTimer.getTime() > maxTime) {
videoTimer.pause();
videoTimer.setTime(maxTime);
final skipUrl = videoList.getCurrentItem().url;
final skipUrl = videoList.currentItem.url;
Timer.delay(() -> {
skipVideo({
type: SkipVideo,
Expand Down Expand Up @@ -694,7 +699,7 @@ class Main {
if (videoList.length == 0) return;
if (!client.isLeader) return;
if (Math.abs(data.setTime.time - videoTimer.getTime()) > FLASHBACK_DIST) {
saveFlashbackTime();
saveFlashbackTime(videoList.currentItem);
}
videoTimer.setTime(data.setTime.time);
broadcastExcept(client, {
Expand All @@ -716,7 +721,7 @@ class Main {
if (videoList.length == 0) return;
data.rewind.time += videoTimer.getTime();
if (data.rewind.time < 0) data.rewind.time = 0;
saveFlashbackTime();
saveFlashbackTime(videoList.currentItem);
videoTimer.setTime(data.rewind.time);
broadcast({
type: data.type,
Expand All @@ -726,7 +731,7 @@ class Main {
case Flashback:
if (!checkPermission(client, RewindPerm)) return;
if (videoList.length == 0) return;
loadFlashbackTime();
loadFlashbackTime(videoList.currentItem);
broadcast({
type: Rewind,
rewind: {
Expand Down Expand Up @@ -762,6 +767,9 @@ class Main {

case PlayItem:
if (!checkPermission(client, ChangeOrderPerm)) return;
if (videoTimer.getTime() > FLASHBACK_DIST) {
saveFlashbackTime(videoList.currentItem);
}
videoList.setPos(data.playItem.pos);
data.playItem.pos = videoList.pos;
restartWaitTimer();
Expand Down Expand Up @@ -790,6 +798,9 @@ class Main {
case ClearPlaylist:
if (isPlaylistLockedFor(client)) return;
if (!checkPermission(client, RemoveVideoPerm)) return;
if (videoTimer.getTime() > FLASHBACK_DIST) {
saveFlashbackTime(videoList.currentItem);
}
videoTimer.stop();
videoList.clear();
broadcast(data);
Expand Down Expand Up @@ -902,8 +913,13 @@ class Main {

function skipVideo(data:WsEvent):Void {
if (videoList.length == 0) return;
final item = videoList.getCurrentItem();
final item = videoList.currentItem;
if (item.url != data.skipVideo.url) return;
final dur = videoList.currentItem.duration;
if (videoTimer.getTime() > FLASHBACK_DIST
&& videoTimer.getTime() < dur - FLASHBACK_DIST) {
saveFlashbackTime(videoList.currentItem);
}
videoList.skipItem();
if (videoList.length > 0) restartWaitTimer();
broadcast(data);
Expand Down Expand Up @@ -959,7 +975,6 @@ class Main {
var loadedClientsCount = 0;

function restartWaitTimer():Void {
if (videoTimer.getTime() > FLASHBACK_DIST) saveFlashbackTime();
videoTimer.stop();
if (waitVideoStart != null) waitVideoStart.stop();
waitVideoStart = Timer.delay(startVideoPlayback, VIDEO_START_MAX_DELAY);
Expand All @@ -979,18 +994,48 @@ class Main {
videoTimer.start();
}

var flashbackTime = 0.0;

function saveFlashbackTime() {
function saveFlashbackTime(item:VideoItem):Void {
final url = item.url;
final duration = item.duration;
final time = videoTimer.getTime();
final flashbackTime = findFlashbackTime(url, duration);
if (Math.abs(flashbackTime - time) < FLASHBACK_DIST) return;
flashbackTime = time;
addRecentFlashback(url, duration, time);
}

function loadFlashbackTime() {
function loadFlashbackTime(item:VideoItem):Void {
final url = item.url;
final duration = item.duration;
final time = videoTimer.getTime();
final flashbackTime = findFlashbackTime(url, duration);
videoTimer.setTime(flashbackTime);
flashbackTime = time;
addRecentFlashback(url, duration, time);
}

function findFlashbackTime(url:String, duration:Float):Float {
return findFlashbackItem(url, duration)?.time ?? 0.0;
}

final flashbackTimes:Array<FlashbackItem> = [];

function findFlashbackItem(url:String, ?duration:Float):Null<FlashbackItem> {
var item = flashbackTimes.find(item -> item.url == url);
// if there is no url match, find recent flashback item with same duration
if (duration != null && item == null) {
item = flashbackTimes.find(item -> item.duration == duration);
}
return item;
}

function addRecentFlashback(url:String, duration:Float, time:Float):Void {
flashbackTimes.remove(findFlashbackItem(url));
flashbackTimes.unshift({
url: url,
duration: duration,
time: time
});
final length = flashbackTimes.count();
if (length > 10) flashbackTimes.pop();
}

function isPlaylistLockedFor(client:Client):Bool {
Expand Down

0 comments on commit c9b920c

Please sign in to comment.