Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions server.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def stop_all_videos():


# terminate a parent process and all its child processes using a specified signal.
def kill_child_processes(parent_pid, sig=signal.SIGKILL):
def kill_child_processes(parent_pid, sig=signal.SIGILL):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL] The change from signal.SIGKILL to signal.SIGILL in kill_child_processes is incorrect. SIGILL (Illegal Instruction) is not intended for process termination and can be caught or ignored by a process, potentially preventing it from being killed. SIGKILL is the appropriate signal for forceful, unblockable termination.

try:
parent = psutil.Process(parent_pid)
parent.send_signal(sig)
Expand Down Expand Up @@ -412,7 +412,7 @@ async def state():


@app.post("/play/file")
async def play_file(file_path: str = "cache", title: str = None, thumbnail: str = None):
async def play_file(file_path: str = "cache", title: str = None, thumbnail: str = None, loop: bool = False):
try:

# check if we are going to play all videos or a single video in the cache
Expand All @@ -427,7 +427,7 @@ async def play_file(file_path: str = "cache", title: str = None, thumbnail: str
args=(
file_path,
State.PLAYING,
False,
loop,
title,
thumbnail,
),
Expand Down
64 changes: 55 additions & 9 deletions static/cache.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ <h3>Cache Storage</h3>
<div id="listOfVideosContainer" >
</div>
<script>
let holdTimer;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL] The togglePlayVideo function is defined twice. The inner definition async function togglePlayVideo(e, video) at line 22 shadows the outer definition async function togglePlayVideo(e, video, isLooping) at line 20. As a result, the isLooping parameter will always be undefined within the function that makes the fetch request, preventing the video looping functionality from working. The inner function should be removed, and the outer function should contain the logic.

document.getElementById('go_back_btn').addEventListener('click', () => {
let url = window.location.href
window.location.href = window.location.href.substring(0, url.lastIndexOf('/') )

});

async function togglePlayVideo(e, video, isLooping) {
let debugUrl = new URL("debug", window.location.href)
async function togglePlayVideo(e, video) {
try {
Expand All @@ -33,13 +36,18 @@ <h3>Cache Storage</h3>
url.searchParams.append("file_path", file_path)
url.searchParams.append("title", title)
url.searchParams.append("thumbnail", thumbnail)
//repeats the video if looping
if (isLooping) {
url.searchParams.append("loop", "true");
}
console.log("Fetching URL:", url.href);
const response = await fetch(url.href, { method: "POST" });
return response.json()
} catch(error) {
console.log(error)
}
}

}
async function togglePlayEntireDirectory(e) {
try {
e.preventDefault()
Expand Down Expand Up @@ -69,17 +77,32 @@ <h3>Cache Storage</h3>
}
}

async function handlePlayButton(e, video) {
async function handlePlayButton(e, video, isLooping) {
const playButton = document.getElementById(video.id)
const response = await togglePlayVideo(e, video)
if (playButton.classList.contains('is-looping') && isLooping) {
let stopURL = new URL(window.location.href.replace('cache', 'stop'));
await fetch(stopURL.href, { method: "POST" });
playButton.textContent = "Stopped";
playButton.style.backgroundColor = "";
playButton.classList.remove('is-looping');
isLooping = false;
setTimeout(() => { playButton.textContent = "play"; }, 2000);
return;
}
const response = await togglePlayVideo(e, video, isLooping)
if (response["detail"] === "Success") {
playButton.textContent = "Success!";
playButton.disabled = true;

setTimeout(() => {
if (isLooping) {
playButton.textContent = "Looping!";
playButton.style.backgroundColor = "green";
playButton.classList.add('is-looping');
} else {
playButton.textContent = "Success!";
playButton.disabled = true;
setTimeout(() => {
playButton.textContent = "Play";
playButton.disabled = false;
}, 2000);
}
} else {
alert(response["detail"]);
}
Expand Down Expand Up @@ -139,10 +162,33 @@ <h3>Cache Storage</h3>
playButton.textContent = 'play';
videoSize.textContent = formatBytes(element.size_bytes);

playButton.addEventListener('click', (e) => {
handlePlayButton(e, element)
//Loops video if held for 750ms
playButton.addEventListener('mousedown', (e)=> {
startTime = Date.now();
holdTimer = setTimeout(() => {
if (playButton.classList.contains('is-looping')) {
playButton.textContent = "Release to STOP";
} else {
playButton.textContent = "Release to LOOP";
}
}, 750);
});

playButton.addEventListener('mouseup', (e) => {
clearTimeout(holdTimer);
const duration = Date.now() - startTime;

if (duration >= 750) {
// It was a long press
handlePlayButton(e, element, true);
} else if (!playButton.classList.contains('is-looping')){
// It was a normal click - reset text if it started changing
playButton.textContent = "play";
playButton.style.backgroundColor = "";
handlePlayButton(e, element, false);
}
});

playEntireDirectoryBtn.addEventListener('click', handlePlayEntireDirectoryButton);

videoImgContainer.appendChild(videoImg);
Expand Down