diff options
author | Mole Shang <[email protected]> | 2023-08-10 14:15:00 +0800 |
---|---|---|
committer | Mole Shang <[email protected]> | 2023-08-10 14:15:00 +0800 |
commit | 6cbcaba2a80c47714e8aa45d021bdcd4965780b1 (patch) | |
tree | 0adcb9b088997689e18fad20a463ea681e4f50b7 | |
parent | ef4918ffeb326751fa17c2c8335963be4e43254f (diff) | |
download | hinata-6cbcaba2a80c47714e8aa45d021bdcd4965780b1.tar.gz hinata-6cbcaba2a80c47714e8aa45d021bdcd4965780b1.tar.bz2 hinata-6cbcaba2a80c47714e8aa45d021bdcd4965780b1.zip |
ui: show progress while remuxing
-rw-r--r-- | src/main.c | 2 | ||||
-rw-r--r-- | src/main.h | 1 | ||||
-rw-r--r-- | src/process_url.c | 5 | ||||
-rw-r--r-- | src/process_url.h | 7 | ||||
-rw-r--r-- | src/status.h | 16 | ||||
-rw-r--r-- | src/ui.c | 30 | ||||
-rw-r--r-- | src/utils/ffmpeg.c | 22 | ||||
-rw-r--r-- | src/utils/ffmpeg.h | 4 | ||||
-rw-r--r-- | src/utils/time_info.c | 8 | ||||
-rw-r--r-- | src/utils/time_info.h | 6 |
10 files changed, 82 insertions, 19 deletions
@@ -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); @@ -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 @@ -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 |