annotate third_party/ffmpeg/ffmpeg_cli.c @ 217:7ef4c9d2a72d hg-web

[DO NOT PUSH] Random values.
author MrJuneJune <me@mrjunejune.com>
date Sun, 25 Jan 2026 10:44:04 -0800
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
217
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
1 #include "ffmpeg_cli.h"
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
2 #include <stdio.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
3 #include <stdlib.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
4 #include <string.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
5 #include <stdarg.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
6 #include <sys/stat.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
7 #include <sys/wait.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
8 #include <errno.h>
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
9
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
10 #define MAX_CMD_LEN 4096
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
11 #define MAX_ERROR_LEN 512
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
12
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
13 static char last_error[MAX_ERROR_LEN] = {0};
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
14
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
15 static void set_error(const char* fmt, ...) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
16 va_list args;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
17 va_start(args, fmt);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
18 vsnprintf(last_error, MAX_ERROR_LEN, fmt, args);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
19 va_end(args);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
20 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
21
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
22 static bool file_exists(const char* path) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
23 struct stat st;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
24 return stat(path, &st) == 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
25 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
26
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
27 static bool ensure_dir(const char* path) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
28 struct stat st;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
29 if (stat(path, &st) == 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
30 return S_ISDIR(st.st_mode);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
31 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
32 return mkdir(path, 0755) == 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
33 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
34
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
35 static int run_command(const char* cmd) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
36 int ret = system(cmd);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
37 if (ret == -1) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
38 set_error("Failed to execute command: %s", strerror(errno));
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
39 return -1;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
40 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
41 return WEXITSTATUS(ret);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
42 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
43
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
44 ImageConvertOpts ffmpeg_image_opts_default(void) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
45 return (ImageConvertOpts){
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
46 .quality = 80,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
47 .max_width = 0,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
48 .max_height = 0,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
49 .preserve_aspect = true,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
50 };
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
51 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
52
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
53 HlsConvertOpts ffmpeg_hls_opts_default(void) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
54 return (HlsConvertOpts){
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
55 .segment_duration = 6,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
56 .video_bitrate = 0,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
57 .audio_bitrate = 128,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
58 .max_width = 0,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
59 .max_height = 0,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
60 .generate_thumbnail = true,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
61 };
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
62 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
63
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
64 bool ffmpeg_is_available(void) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
65 return system("ffmpeg -version > /dev/null 2>&1") == 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
66 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
67
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
68 const char* ffmpeg_last_error(void) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
69 return last_error;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
70 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
71
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
72 FfmpegResult ffmpeg_image_to_webp(const char* input_path, const char* output_path, ImageConvertOpts* opts) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
73 if (!input_path || !output_path) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
74 set_error("Invalid arguments: input_path and output_path required");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
75 return FFMPEG_ERR_INVALID_ARGS;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
76 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
77
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
78 if (!file_exists(input_path)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
79 set_error("Input file not found: %s", input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
80 return FFMPEG_ERR_INPUT_NOT_FOUND;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
81 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
82
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
83 ImageConvertOpts default_opts = ffmpeg_image_opts_default();
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
84 if (!opts) opts = &default_opts;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
85
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
86 char cmd[MAX_CMD_LEN];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
87 char scale_filter[256] = "";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
88
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
89 // Build scale filter if resizing
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
90 if (opts->max_width > 0 || opts->max_height > 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
91 int w = opts->max_width > 0 ? opts->max_width : -1;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
92 int h = opts->max_height > 0 ? opts->max_height : -1;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
93
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
94 if (opts->preserve_aspect) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
95 if (w > 0 && h > 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
96 snprintf(scale_filter, sizeof(scale_filter),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
97 "-vf \"scale='min(%d,iw)':min'(%d,ih)':force_original_aspect_ratio=decrease\"", w, h);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
98 } else if (w > 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
99 snprintf(scale_filter, sizeof(scale_filter), "-vf \"scale='min(%d,iw)':-1\"", w);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
100 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
101 snprintf(scale_filter, sizeof(scale_filter), "-vf \"scale=-1:'min(%d,ih)'\"", h);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
102 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
103 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
104 snprintf(scale_filter, sizeof(scale_filter), "-vf \"scale=%d:%d\"", w, h);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
105 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
106 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
107
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
108 snprintf(cmd, sizeof(cmd),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
109 "ffmpeg -y -i \"%s\" %s -quality %d \"%s\" 2>/dev/null",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
110 input_path, scale_filter, opts->quality, output_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
111
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
112 int ret = run_command(cmd);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
113 if (ret != 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
114 set_error("FFmpeg conversion failed with code %d", ret);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
115 return FFMPEG_ERR_PROCESS_FAILED;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
116 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
117
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
118 if (!file_exists(output_path)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
119 set_error("Output file was not created");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
120 return FFMPEG_ERR_OUTPUT_FAILED;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
121 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
122
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
123 return FFMPEG_OK;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
124 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 FfmpegResult ffmpeg_video_to_hls(const char* input_path, const char* output_dir, const char* name, HlsConvertOpts* opts) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 if (!input_path || !output_dir || !name) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 set_error("Invalid arguments: input_path, output_dir, and name required");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 return FFMPEG_ERR_INVALID_ARGS;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 if (!file_exists(input_path)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
133 set_error("Input file not found: %s", input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 return FFMPEG_ERR_INPUT_NOT_FOUND;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
135 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 if (!ensure_dir(output_dir)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 set_error("Failed to create output directory: %s", output_dir);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 return FFMPEG_ERR_OUTPUT_FAILED;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
142 HlsConvertOpts default_opts = ffmpeg_hls_opts_default();
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
143 if (!opts) opts = &default_opts;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
144
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
145 char cmd[MAX_CMD_LEN];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 char scale_filter[256] = "";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 char video_bitrate[64] = "";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 char audio_bitrate[64] = "";
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 // Build scale filter if resizing
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 if (opts->max_width > 0 || opts->max_height > 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 int w = opts->max_width > 0 ? opts->max_width : -2;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 int h = opts->max_height > 0 ? opts->max_height : -2;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 snprintf(scale_filter, sizeof(scale_filter), "-vf \"scale=%d:%d\"", w, h);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
156
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 // Video bitrate
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 if (opts->video_bitrate > 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 snprintf(video_bitrate, sizeof(video_bitrate), "-b:v %dk", opts->video_bitrate);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 // Audio bitrate
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 snprintf(audio_bitrate, sizeof(audio_bitrate), "-b:a %dk",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164 opts->audio_bitrate > 0 ? opts->audio_bitrate : 128);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 char playlist_path[1024];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 char segment_pattern[1024];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 snprintf(playlist_path, sizeof(playlist_path), "%s/%s.m3u8", output_dir, name);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 snprintf(segment_pattern, sizeof(segment_pattern), "%s/%s_%%03d.ts", output_dir, name);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 // Main HLS conversion command
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
172 snprintf(cmd, sizeof(cmd),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173 "ffmpeg -y -i \"%s\" "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 "-c:v libx264 -preset fast -crf 22 %s %s "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 "-c:a aac %s "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 "-f hls "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 "-hls_time %d "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 "-hls_list_size 0 "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
179 "-hls_segment_filename \"%s\" "
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
180 "\"%s\" 2>/dev/null",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
181 input_path,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
182 scale_filter, video_bitrate,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
183 audio_bitrate,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
184 opts->segment_duration,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
185 segment_pattern,
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
186 playlist_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
187
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
188 int ret = run_command(cmd);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
189 if (ret != 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
190 set_error("FFmpeg HLS conversion failed with code %d", ret);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
191 return FFMPEG_ERR_PROCESS_FAILED;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
192 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
193
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
194 // Generate thumbnail if requested
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
195 if (opts->generate_thumbnail) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
196 char thumb_path[1024];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
197 snprintf(thumb_path, sizeof(thumb_path), "%s/%s_thumb.jpg", output_dir, name);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
198 ffmpeg_video_thumbnail(input_path, thumb_path, 1);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
199 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
200
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
201 return FFMPEG_OK;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
202 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
203
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
204 FfmpegResult ffmpeg_video_thumbnail(const char* input_path, const char* output_path, int timestamp_seconds) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
205 if (!input_path || !output_path) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
206 set_error("Invalid arguments: input_path and output_path required");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
207 return FFMPEG_ERR_INVALID_ARGS;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
208 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
209
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
210 if (!file_exists(input_path)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211 set_error("Input file not found: %s", input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
212 return FFMPEG_ERR_INPUT_NOT_FOUND;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
213 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
214
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
215 char cmd[MAX_CMD_LEN];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216 snprintf(cmd, sizeof(cmd),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
217 "ffmpeg -y -i \"%s\" -ss %d -vframes 1 -q:v 2 \"%s\" 2>/dev/null",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
218 input_path, timestamp_seconds, output_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
219
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
220 int ret = run_command(cmd);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
221 if (ret != 0) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
222 set_error("FFmpeg thumbnail generation failed with code %d", ret);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
223 return FFMPEG_ERR_PROCESS_FAILED;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
224 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
225
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
226 return FFMPEG_OK;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
227 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
228
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
229 FfmpegResult ffmpeg_get_duration(const char* input_path, double* duration_out) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
230 if (!input_path || !duration_out) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
231 set_error("Invalid arguments");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
232 return FFMPEG_ERR_INVALID_ARGS;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
233 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
234
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 if (!file_exists(input_path)) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
236 set_error("Input file not found: %s", input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
237 return FFMPEG_ERR_INPUT_NOT_FOUND;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
238 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
239
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
240 char cmd[MAX_CMD_LEN];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
241 snprintf(cmd, sizeof(cmd),
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
242 "ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 \"%s\" 2>/dev/null",
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
243 input_path);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
244
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
245 FILE* fp = popen(cmd, "r");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
246 if (!fp) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
247 set_error("Failed to run ffprobe");
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
248 return FFMPEG_ERR_PROCESS_FAILED;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
249 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
250
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
251 char output[64];
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
252 if (fgets(output, sizeof(output), fp) != NULL) {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
253 *duration_out = atof(output);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
254 } else {
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
255 *duration_out = 0;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
256 }
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
257
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
258 pclose(fp);
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
259 return FFMPEG_OK;
7ef4c9d2a72d [DO NOT PUSH] Random values.
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
260 }