Skip to content

Commit 7aeda94

Browse files
committed
Initial commit
1 parent a5ee199 commit 7aeda94

8 files changed

+135
-8
lines changed

CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,7 @@ add_executable(
799799
src/guess_uri.c
800800
src/cir.c
801801
src/sleep.c
802+
src/dump.c
802803
src/threads.c
803804
)
804805

src/clioptions.c

+13
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,18 @@ int clioptions_parse(
719719
}
720720

721721
options->prefer_ffmpegc = 1;
722+
} else if (strcmp(arg->key, "dump") == 0) {
723+
if (options->dump) {
724+
err = M3U8ERR_CLI_DUPLICATE_ARGUMENT;
725+
goto end;
726+
}
727+
728+
if (arg->value != NULL) {
729+
err = M3U8ERR_CLI_VALUE_UNEXPECTED;
730+
goto end;
731+
}
732+
733+
options->dump = 1;
722734
} else if (strcmp(arg->key, "return-error-code") == 0) {
723735
if (options->return_error_code) {
724736
err = M3U8ERR_CLI_DUPLICATE_ARGUMENT;
@@ -827,6 +839,7 @@ void clioptions_free(struct CLIOptions* const options) {
827839
options->disable_autoselection = 0;
828840
options->disable_progress = 0;
829841
options->prefer_ffmpegc = 0;
842+
options->dump = 0;
830843
options->all_medias_selected = 0;
831844
options->http10 = 0;
832845
options->http11 = 0;

src/clioptions.h

+1
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct CLIOptions {
4242
int disable_autoselection;
4343
int disable_progress;
4444
int prefer_ffmpegc;
45+
int dump;
4546
int return_error_code;
4647
int all_medias_selected;
4748
size_t selected_stream;

src/dump.c

+101-4
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ static void json_array_end(const int indentation) {
176176

177177
}
178178

179-
void dump_segments(const struct M3U8Stream* const stream) {
179+
static void dump_segments(const struct M3U8Stream* const stream) {
180180

181181
size_t index = 0;
182182
size_t subindex = 0;
@@ -449,7 +449,7 @@ void dump_segments(const struct M3U8Stream* const stream) {
449449

450450
}
451451

452-
void dump_media_stream(
452+
static void dump_media_stream(
453453
const struct M3U8Stream* const stream,
454454
const struct M3U8StreamItem* const item
455455
) {
@@ -626,7 +626,7 @@ void dump_media_stream(
626626

627627
}
628628

629-
void dump_variant_stream(
629+
static void dump_variant_stream(
630630
const struct M3U8Stream* const stream,
631631
const struct M3U8StreamItem* const item
632632
) {
@@ -851,7 +851,91 @@ void dump_variant_stream(
851851

852852
}
853853

854-
void dump_master_playlist(const struct M3U8Stream* const stream) {
854+
static void dump_media_playlist(const struct M3U8Stream* const stream) {
855+
856+
const bigfloat_t duration = m3u8stream_getduration(stream);
857+
const biguint_t segments = m3u8stream_getsegments(stream);
858+
const bigfloat_t average_duration = duration / (segments > 0 ? segments : 1);
859+
860+
json_object_begin(0);
861+
862+
/* Type */
863+
put_jkey(KTYPE, 1);
864+
json_object_begin(0);
865+
866+
put_jkey(KID, 2);
867+
put_jvalue_uint(stream->playlist.type);
868+
869+
put_jdelimiter();
870+
871+
put_jkey(KNAME, 2);
872+
put_jvalue_string("Media Playlist");
873+
874+
printf("\n");
875+
876+
json_object_end(1);
877+
878+
put_jdelimiter();
879+
880+
/* Streams */
881+
put_jkey(KSTREAMS, 1);
882+
883+
json_array_begin(0);
884+
885+
json_object_begin(2);
886+
887+
/* Type */
888+
put_jkey(KTYPE, 3);
889+
put_jvalue_null();
890+
891+
put_jdelimiter();
892+
893+
/* Duration */
894+
put_jkey(KDURATION, 3);
895+
put_jvalue_uint(duration);
896+
897+
put_jdelimiter();
898+
899+
/* Average duration */
900+
put_jkey(KAVERAGE_DURATION, 3);
901+
put_jvalue_uint(average_duration);
902+
903+
put_jdelimiter();
904+
905+
/* Segments */
906+
put_jkey(KSEGMENTS, 3);
907+
put_jvalue_uint(segments);
908+
909+
put_jdelimiter();
910+
911+
/* Media */
912+
put_jkey(KMEDIA, 3);
913+
914+
json_array_begin(0);
915+
916+
dump_segments(stream);
917+
918+
printf("\n");
919+
920+
json_array_end(3);
921+
922+
printf("\n");
923+
924+
json_object_end(2);
925+
926+
printf("\n");
927+
928+
json_array_end(1);
929+
930+
printf("\n");
931+
932+
json_object_end(0);
933+
934+
printf("\n");
935+
936+
}
937+
938+
static void dump_master_playlist(const struct M3U8Stream* const stream) {
855939

856940
int begin = 1;
857941

@@ -929,4 +1013,17 @@ void dump_master_playlist(const struct M3U8Stream* const stream) {
9291013

9301014
printf("\n");
9311015

1016+
}
1017+
1018+
void dump_playlist(const struct M3U8Stream* const stream) {
1019+
1020+
switch (stream->playlist.type) {
1021+
case M3U8_PLAYLIST_TYPE_MASTER:
1022+
dump_master_playlist(stream);
1023+
break;
1024+
case M3U8_PLAYLIST_TYPE_MEDIA:
1025+
dump_media_playlist(stream);
1026+
break;
1027+
}
1028+
9321029
}

src/dump.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,6 @@
1-
void dump_master_playlist(const struct M3U8Stream* const stream);
1+
#if !defined(DUMP_H)
2+
#define DUMP_H
3+
4+
void dump_playlist(const struct M3U8Stream* const stream);
5+
6+
#endif

src/main.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ int main(int argc, argv_t* argv[]) {
246246
goto end;
247247
}
248248

249-
dump_master_playlist(&stream);
250-
goto end;
249+
if (options.dump) {
250+
dump_playlist(&stream);
251+
goto end;
252+
}
251253

252254
if (options.show_formats) {
253255
show_formats(&stream);

src/program_help.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This file is auto-generated. Use the tool at ../tools/program_help.h.py to regen
66
#define PROGRAM_HELP_H
77

88
#define PROGRAM_HELP \
9-
"usage: kai [-h] [-v] -u URL --max-redirs MAX_REDIRS [-k] [-A USER_AGENT] [-x URI] [--doh-url URL] [-e URL] [-r COUNT] [-H HEADER] [--disable-cookies] [--http1.0] [--http1.1] [--http2] [--verbose] [-y] [-S] [--select-media MEDIA] [--select-stream VARIANT_STREAM] [--disable-autoselection] [--disable-progress-meter] [--prefer-ffmpeg-cli] [-c CONCURRENCY] [-o FILENAME] [--randomized-temporary-directory] [--return-error-code]\n"\
9+
"usage: kai [-h] [-v] -u URL --max-redirs MAX_REDIRS [-k] [-A USER_AGENT] [-x URI] [--doh-url URL] [-e URL] [-r COUNT] [-H HEADER] [--disable-cookies] [--http1.0] [--http1.1] [--http2] [--verbose] [-y] [-S] [--select-media MEDIA] [--select-stream VARIANT_STREAM] [--disable-autoselection] [--disable-progress-meter] [--prefer-ffmpeg-cli] [--dump] [-c CONCURRENCY] [-o FILENAME] [--randomized-temporary-directory] [--return-error-code]\n"\
1010
"\n"\
1111
"A command-line utility to download contents from M3U8 playlists.\n"\
1212
"\n"\
@@ -42,6 +42,7 @@ This file is auto-generated. Use the tool at ../tools/program_help.h.py to regen
4242
" --disable-progress-meter\n"\
4343
" Disable showing download progress meter.\n"\
4444
" --prefer-ffmpeg-cli Prefer using the FFmpeg CLI tool instead of the builtin implementation when muxing media streams.\n"\
45+
" --dump Dump a JSON tree of the M3U8 playlist.\n"\
4546
" -c CONCURRENCY, --concurrency CONCURRENCY\n"\
4647
" Specify how many media segments should be downloaded simultaneously. Defaults to the number of CPU cores available.\n"\
4748
" -o FILENAME, --output FILENAME\n"\

tools/program_help.h.py

+7
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@
181181
help = "Prefer using the FFmpeg CLI tool instead of the builtin implementation when muxing media streams."
182182
)
183183

184+
parser.add_argument(
185+
"--dump",
186+
required = False,
187+
action = "store_true",
188+
help = "Dump a JSON tree of the M3U8 playlist."
189+
)
190+
184191
parser.add_argument(
185192
"-c",
186193
"--concurrency",

0 commit comments

Comments
 (0)