aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2022-03-11 10:45:01 +0100
committerdec05eba <dec05eba@protonmail.com>2022-03-11 10:45:01 +0100
commitd92f6d7725720e3facf90b0fdefc1ef4eb1c2227 (patch)
tree6a4091eef23f56545431cdc0ef227efbc576b2b3
parent5fb94ed3fbd0e3942632ad617f803727ecf54169 (diff)
youtube video: fix video with redirect not getting content length correctly, re-enable youtube timestamp
-rw-r--r--TODO1
-rw-r--r--src/Downloader.cpp19
-rw-r--r--src/plugins/Youtube.cpp4
-rw-r--r--video_player/src/main.cpp47
4 files changed, 51 insertions, 20 deletions
diff --git a/TODO b/TODO
index d8408a0..a530f0e 100644
--- a/TODO
+++ b/TODO
@@ -223,5 +223,4 @@ Zero clear password memory after use.
Periodically cleanup old cache files (especially manga images, thumbnails and media). Maybe have a file that says when we last checked for old files,
and if its X days old then check and remove old files again and update the file.
Render watch progress in youtube.
-Readd youtube watch progress which seems to be broken because of frozen download?
Set _NET_WM_USER_TIME (see sfml). \ No newline at end of file
diff --git a/src/Downloader.cpp b/src/Downloader.cpp
index cb9f448..57a0349 100644
--- a/src/Downloader.cpp
+++ b/src/Downloader.cpp
@@ -310,8 +310,20 @@ namespace QuickMedia {
return offset;
}
+ static ssize_t read_eintr(int fd, void *buffer, size_t size) {
+ while(true) {
+ ssize_t bytes_read = read(fd, buffer, size);
+ if(bytes_read == -1) {
+ if(errno != EINTR)
+ return -1;
+ } else {
+ return bytes_read;
+ }
+ }
+ }
+
static int64_t read_fn(YoutubeReadProgram *program, char *buf, uint64_t nbytes) {
- ssize_t bytes_read = read(program->read_program.read_fd, buf, nbytes);
+ ssize_t bytes_read = read_eintr(program->read_program.read_fd, buf, nbytes);
if(bytes_read > 0) {
program->offset += bytes_read;
program->bytes_downloaded += bytes_read;
@@ -319,15 +331,12 @@ namespace QuickMedia {
// End of current range, progress to next range
bytes_read = seek_fn(program, program->offset);
if(bytes_read >= 0) {
- bytes_read = read(program->read_program.read_fd, buf, nbytes);
+ bytes_read = read_eintr(program->read_program.read_fd, buf, nbytes);
if(bytes_read > 0) {
program->offset += bytes_read;
program->bytes_downloaded += bytes_read;
}
}
- } else if(bytes_read < 0) {
- if(errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN)
- return 0;
}
return bytes_read;
}
diff --git a/src/plugins/Youtube.cpp b/src/plugins/Youtube.cpp
index df79701..2d92cd8 100644
--- a/src/plugins/Youtube.cpp
+++ b/src/plugins/Youtube.cpp
@@ -1860,7 +1860,6 @@ namespace QuickMedia {
}
std::string YoutubeVideoPage::get_url_timestamp() {
- #if 0
if(!timestamp.empty())
return timestamp;
@@ -1882,9 +1881,6 @@ namespace QuickMedia {
return "";
else
return std::to_string(it->second.time_pos_sec);
- #else
- return timestamp;
- #endif
}
BodyItems YoutubeVideoPage::get_related_media(const std::string &url) {
diff --git a/video_player/src/main.cpp b/video_player/src/main.cpp
index 42a9b4f..4ec9278 100644
--- a/video_player/src/main.cpp
+++ b/video_player/src/main.cpp
@@ -409,7 +409,7 @@ static int64_t size_fn(void *cookie) {
buffer.resize(8192);
size_t read_offset = 0;
for(;;) {
- ssize_t bytes_read = read(header_program.read_fd, &buffer[read_offset], buffer.size() - read_offset);
+ ssize_t bytes_read = read_eintr(header_program.read_fd, &buffer[read_offset], buffer.size() - read_offset);
if(bytes_read == 0) {
buffer.resize(read_offset);
break;
@@ -448,26 +448,36 @@ static int64_t size_fn(void *cookie) {
close(header_program.read_fd);
if(res == 0) {
- size_t content_length_index = str_find_case_insensitive(buffer, 0, "content-length:", 15);
+ size_t header_start = str_find_case_insensitive(buffer, 0, "200 OK", 6);
+ if(header_start == std::string::npos)
+ goto end;
+
+ header_start += 6;
+ size_t content_length_index = str_find_case_insensitive(buffer, header_start, "content-length:", 15);
if(content_length_index == std::string::npos)
- return res;
+ goto end;
content_length_index += 15;
size_t content_length_end = buffer.find('\r', content_length_index);
if(content_length_end == std::string::npos)
- return res;
+ goto end;
buffer[content_length_end] = '\0';
errno = 0;
char *endptr;
int64_t content_length = strtoll(&buffer[content_length_index], &endptr, 10);
if(endptr == &buffer[content_length_index] || errno != 0)
- return res;
+ goto end;
res = content_length;
}
+ end:
program->content_length = res;
+ if(res < 0) {
+ fprintf(stderr, "Error: video size failed\n");
+ exit(2);
+ }
return res;
}
@@ -497,26 +507,32 @@ static int64_t seek_fn(void *cookie, int64_t offset) {
"-g", "-s", "-L", "-f",
"-r", range, "--", program->url, nullptr };
int res = exec_program_pipe(args, program);
- if(res != 0)
- return MPV_ERROR_GENERIC;
+ if(res != 0) {
+ fprintf(stderr, "Error: video seek failed\n");
+ exit(2);
+ }
return offset;
}
static int64_t read_fn(void *cookie, char *buf, uint64_t nbytes) {
ReadProgram *program = (ReadProgram*)cookie;
- ssize_t bytes_read = read(program->read_fd, buf, nbytes);
+ ssize_t bytes_read = read_eintr(program->read_fd, buf, nbytes);
if(bytes_read > 0) {
program->offset += bytes_read;
} else if(bytes_read == 0) {
// End of current range, progress to next range
bytes_read = seek_fn(program, program->offset);
if(bytes_read >= 0) {
- bytes_read = read(program->read_fd, buf, nbytes);
+ bytes_read = read_eintr(program->read_fd, buf, nbytes);
if(bytes_read > 0)
program->offset += bytes_read;
}
}
+ if(bytes_read < 0) {
+ fprintf(stderr, "Error: video read failed\n");
+ exit(2);
+ }
return bytes_read;
}
@@ -550,6 +566,10 @@ static int open_fn(void*, char *uri, mpv_stream_cb_info *info) {
read_program->url = strdup((const char*)uri + 8);
read_program->offset = 0;
int64_t res = seek_fn(read_program, read_program->offset);
+ if(res < 0) {
+ fprintf(stderr, "Error: video open failed\n");
+ exit(2);
+ }
info->cookie = read_program;
info->size_fn = size_fn;
@@ -601,6 +621,7 @@ int main(int argc, char **argv) {
std::string json_errors;
bool file_started = false;
+ int exit_code = 0;
while (running) {
mpv_event *event = mpv_wait_event(mpv_ctx, -1.0);
@@ -613,6 +634,12 @@ int main(int argc, char **argv) {
} else if(event->event_id == MPV_EVENT_SHUTDOWN) {
running = false;
break;
+ } else if(event->event_id == MPV_EVENT_END_FILE) {
+ mpv_event_end_file *end_file_event = (mpv_event_end_file*)event->data;
+ if(end_file_event->error == MPV_END_FILE_REASON_ERROR) {
+ exit_code = 2;
+ break;
+ }
} else if(event->event_id == MPV_EVENT_PROPERTY_CHANGE) {
// End of file (idle)
mpv_event_property *property = (mpv_event_property*)event->data;
@@ -637,5 +664,5 @@ int main(int argc, char **argv) {
}
mpv_terminate_destroy(mpv_ctx);
- return 0;
+ return exit_code;
}