summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMole Shang <[email protected]>2023-08-10 14:15:00 +0800
committerMole Shang <[email protected]>2023-08-10 14:15:00 +0800
commit6cbcaba2a80c47714e8aa45d021bdcd4965780b1 (patch)
tree0adcb9b088997689e18fad20a463ea681e4f50b7
parentef4918ffeb326751fa17c2c8335963be4e43254f (diff)
downloadhinata-6cbcaba2a80c47714e8aa45d021bdcd4965780b1.tar.gz
hinata-6cbcaba2a80c47714e8aa45d021bdcd4965780b1.tar.bz2
hinata-6cbcaba2a80c47714e8aa45d021bdcd4965780b1.zip
ui: show progress while remuxing
-rw-r--r--src/main.c2
-rw-r--r--src/main.h1
-rw-r--r--src/process_url.c5
-rw-r--r--src/process_url.h7
-rw-r--r--src/status.h16
-rw-r--r--src/ui.c30
-rw-r--r--src/utils/ffmpeg.c22
-rw-r--r--src/utils/ffmpeg.h4
-rw-r--r--src/utils/time_info.c8
-rw-r--r--src/utils/time_info.h6
10 files changed, 82 insertions, 19 deletions
diff --git a/src/main.c b/src/main.c
index ecd9381..4930b1c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -29,6 +29,7 @@
#include "style.h"
#include "ui.h"
#include "unifont.h"
+#include "utils/ffmpeg.h"
extern int win_width, win_height;
static char *cookie;
@@ -118,6 +119,7 @@ int main(void) {
status_t stat = {0};
stat.is_done = true;
ui.stat = &stat;
+ setup_stat(&stat);
/* create context */
ui.ctx = nk_glfw3_init(&glfw, win, NK_GLFW3_INSTALL_CALLBACKS);
diff --git a/src/main.h b/src/main.h
index 6a319d4..731a508 100644
--- a/src/main.h
+++ b/src/main.h
@@ -1,6 +1,7 @@
#ifndef MAIN_H_
#define MAIN_H_
+#include <stdbool.h>
#include <stdio.h>
int win_width = 800, win_height = 600;
diff --git a/src/process_url.c b/src/process_url.c
index 713e48c..9b1fa86 100644
--- a/src/process_url.c
+++ b/src/process_url.c
@@ -522,14 +522,15 @@ void poll_status(status_t *stat) {
DEBUG_PRINT("Creating download task failed.\n");
};
stat->is_done = false;
+ stat->type = SIZE_BYTES;
}
if (curl_conf) {
curl_conf->dlnow = 0L;
for (unsigned char i = 0; i < curl_conf->total_thrd; i++) {
curl_conf->dlnow += curl_conf->dlnow_per_thrd[i];
}
- stat->cur = curl_conf->dlnow;
- stat->total = curl_conf->dltotal;
+ stat->cur = (unsigned long)curl_conf->dlnow;
+ stat->total = (unsigned long)curl_conf->dltotal;
DEBUG_PRINT("success_thrd: %hhu, total_thrd: %hhu, is_done: %s\n",
curl_conf->success_thrd, curl_conf->total_thrd,
stat->is_done ? "yes" : "no");
diff --git a/src/process_url.h b/src/process_url.h
index 8a5e59c..a98d05a 100644
--- a/src/process_url.h
+++ b/src/process_url.h
@@ -7,6 +7,7 @@
#include "constants.h"
#include "utils/utils.h"
+#include "status.h"
#define ERRTOSTRING(err) curl_easy_strerror(err)
#define logerr(X) \
@@ -33,12 +34,6 @@ typedef struct thrd_info {
char range[UCHAR_MAX];
} thrd_info_t;
-typedef struct status {
- curl_off_t cur;
- curl_off_t total;
- bool is_done;
-} status_t;
-
typedef struct str_data {
char *string;
size_t len;
diff --git a/src/status.h b/src/status.h
new file mode 100644
index 0000000..97f8a4e
--- /dev/null
+++ b/src/status.h
@@ -0,0 +1,16 @@
+#ifndef STATUS_H_
+#define STATUS_H_
+
+#include <stdbool.h>
+
+typedef enum stat_type { SIZE_BYTES, TIME_SECS } stat_type_t;
+
+typedef struct status {
+ unsigned long cur;
+ unsigned long total;
+ bool is_done;
+ stat_type_t type;
+} status_t;
+
+
+#endif
diff --git a/src/ui.c b/src/ui.c
index a54c9aa..a36bb8e 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -5,12 +5,14 @@
#include <string.h>
#include "nuklear.h"
+#include "process_url.h"
#include "tinyfiledialogs.h"
#include "constants.h"
#include "logger.h"
#include "ui.h"
#include "utils/size_info.h"
+#include "utils/time_info.h"
static nk_size pct;
static bool show_app_about;
@@ -27,14 +29,27 @@ void load_ui(struct ui_struct *ui) {
poll_status(ui->stat);
if (ui->stat->total) {
pct = (ui->stat->cur) * 100 / (ui->stat->total);
- size_info_t info_cur = num2sizeinfo((unsigned long)ui->stat->cur);
- size_info_t info_total = num2sizeinfo((unsigned long)ui->stat->total);
- sprintf(status_string, "%.2Lf%s/%.2Lf%s, %hhu%%", info_cur.n,
- info_cur.unit_str, info_total.n, info_total.unit_str,
- (unsigned char)pct);
+ if (ui->stat->type == SIZE_BYTES) {
+ size_info_t info_cur = num2sizeinfo(ui->stat->cur);
+ size_info_t info_total = num2sizeinfo(ui->stat->total);
+ sprintf(status_string, "%.2Lf%s/%.2Lf%s, %hhu%%", info_cur.n,
+ info_cur.unit_str, info_total.n, info_total.unit_str,
+ (unsigned char)pct);
+ } else if (ui->stat->type == TIME_SECS) {
+ char *cur_ts = malloc(9), *total_ts = malloc(9);
+ sec2timestamp(ui->stat->cur, (char **)&cur_ts);
+ sec2timestamp(ui->stat->total, (char **)&total_ts);
+
+ sprintf(status_string, "%s/%s, %hhu%%", cur_ts, total_ts,
+ (unsigned char)pct);
+ free_and_nullify((void **)&cur_ts);
+ free_and_nullify((void **)&total_ts);
+ }
}
if (ui->stat->is_done) {
- (ui->stat->total) = 0; // To prevent nuklear further updating status_string
+ // (ui->stat->total) = 0; // To prevent nuklear further updating
+ // status_string
+ ui->stat->type = TIME_SECS; // Set for the callback stat
}
nk_menubar_begin(ui->ctx);
@@ -56,7 +71,8 @@ void load_ui(struct ui_struct *ui) {
if (nk_popup_begin(ui->ctx, NK_POPUP_STATIC, "About", NK_WINDOW_CLOSABLE,
s)) {
nk_layout_row_dynamic(ui->ctx, 30, 1);
- nk_label(ui->ctx, "A cross-platform multi-thread downloader", NK_TEXT_LEFT);
+ nk_label(ui->ctx, "A cross-platform multi-thread downloader",
+ NK_TEXT_LEFT);
nk_label(ui->ctx, "By Mole Shang", NK_TEXT_LEFT);
SPACER;
nk_label(ui->ctx, "hinata is licensed under LGPL-3.0.", NK_TEXT_LEFT);
diff --git a/src/utils/ffmpeg.c b/src/utils/ffmpeg.c
index 98d2ba1..8a6d114 100644
--- a/src/utils/ffmpeg.c
+++ b/src/utils/ffmpeg.c
@@ -9,6 +9,8 @@
#include "../logger.h"
#include "ffmpeg.h"
+static status_t *stat_g;
+
#ifdef DEBUG
static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt,
const char *tag) {
@@ -28,6 +30,8 @@ static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt,
}
#endif
+void setup_stat(status_t *stat) { stat_g = stat; }
+
int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
AVFormatContext *input1_format_context = NULL, *input2_format_context = NULL,
*output_format_context = NULL;
@@ -66,6 +70,8 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
goto end;
}
+ stat_g->total = input1_format_context->duration / AV_TIME_BASE;
+
avformat_alloc_output_context2(&output_format_context, NULL, NULL, outfn);
if (!output_format_context) {
append_log("Could not create output context\n");
@@ -172,6 +178,9 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
out_stream->time_base);
packet.pos = -1;
// log_packet(output_format_context, &packet, "out");
+ stat_g->cur = (stat_g->cur <= stat_g->total)
+ ? av_q2d(in_stream->time_base) * packet.pts
+ : stat_g->total;
ret = av_interleaved_write_frame(output_format_context, &packet);
if (ret < 0) {
@@ -196,7 +205,7 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
streams_list[packet.stream_index + input1_format_context->nb_streams];
out_stream = output_format_context->streams[packet.stream_index];
/* copy packet */
- log_packet(input2_format_context, &packet, "in");
+ // log_packet(input2_format_context, &packet, "in");
packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base,
out_stream->time_base,
AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
@@ -206,8 +215,10 @@ int merge_av(const char *videofn, const char *audiofn, const char *outfn) {
packet.duration = av_rescale_q(packet.duration, in_stream->time_base,
out_stream->time_base);
packet.pos = -1;
- log_packet(output_format_context, &packet, "out");
-
+ // log_packet(output_format_context, &packet, "out");
+ stat_g->cur = (stat_g->cur <= stat_g->total)
+ ? av_q2d(in_stream->time_base) * packet.pts
+ : stat_g->total;
ret = av_interleaved_write_frame(output_format_context, &packet);
if (ret < 0) {
append_log("Error muxing packet\n");
@@ -271,6 +282,7 @@ int remux(const char *in_filename, const char *out_filename) {
DEBUG_PRINT("duration: %.2Lf\n",
(long double)ifmt_ctx->duration / AV_TIME_BASE);
+ stat_g->total = ifmt_ctx->duration / AV_TIME_BASE;
av_dump_format(ifmt_ctx, 0, in_filename, 0);
@@ -356,7 +368,9 @@ int remux(const char *in_filename, const char *out_filename) {
av_packet_rescale_ts(pkt, in_stream->time_base, out_stream->time_base);
pkt->pos = -1;
// log_packet(ofmt_ctx, pkt, "out");
-
+ stat_g->cur = (stat_g->cur <= stat_g->total)
+ ? av_q2d(in_stream->time_base) * pkt->pts
+ : stat_g->total;
ret = av_interleaved_write_frame(ofmt_ctx, pkt);
/* pkt is now blank (av_interleaved_write_frame() takes ownership of
* its contents and resets pkt), so that no unreferencing is necessary.
diff --git a/src/utils/ffmpeg.h b/src/utils/ffmpeg.h
index 1ca949d..1dae806 100644
--- a/src/utils/ffmpeg.h
+++ b/src/utils/ffmpeg.h
@@ -1,6 +1,10 @@
#ifndef FFMPEG_H_
#define FFMPEG_H_
+#include "../status.h"
+
+void setup_stat(status_t *status);
+
int merge_av(const char *videofn, const char *audiofn, const char *outfn);
int remux(const char *inputfn, const char *outfn);
diff --git a/src/utils/time_info.c b/src/utils/time_info.c
new file mode 100644
index 0000000..f825a72
--- /dev/null
+++ b/src/utils/time_info.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+void sec2timestamp(int seconds, char **p_ts) {
+ int hours = seconds / 3600;
+ int minutes = (seconds % 3600) / 60;
+ int secs = seconds % 60;
+ sprintf(*p_ts, "%02d:%02d:%02d", hours, minutes, secs);
+}
diff --git a/src/utils/time_info.h b/src/utils/time_info.h
new file mode 100644
index 0000000..35bf256
--- /dev/null
+++ b/src/utils/time_info.h
@@ -0,0 +1,6 @@
+#ifndef TIME_INFO_H_
+#define TIME_INFO_H_
+
+void sec2timestamp(int seconds, char **p_ts);
+
+#endif