Skip to content

Commit

Permalink
Make chapters accurate after cutting
Browse files Browse the repository at this point in the history
  • Loading branch information
faissaloo committed Jan 23, 2021
1 parent c9ba3f9 commit 3fc04d9
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 14 deletions.
23 changes: 19 additions & 4 deletions src/sponskrub/ffwrap.d
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,29 @@ ChapterTime[] get_chapter_times(string filename) {
}
import std.stdio;

bool run_ffmpeg_filter(string input_filename, string output_filename, string filter, FileCategory category) {
bool run_ffmpeg_filter(string input_filename, string output_filename, string filter, FileCategory category, string metadata = "") {
string metadata_filename = null;
scope(exit) {
if (metadata_filename !is null) {
remove(metadata_filename);
}
}

string[] args;
args = ["ffmpeg", "-loglevel", "warning", "-hide_banner", "-stats", "-i", input_filename];

if (metadata != "") {
metadata_filename = prepend_random_prefix(6, "-metadata.ffm");
write_metadata(metadata_filename, metadata);
args ~= ["-i", metadata_filename, "-map_metadata", "0", "-map_chapters", "1"];
}

if (category == FileCategory.AUDIO_VIDEO) {
args = ["ffmpeg", "-loglevel", "warning", "-hide_banner", "-stats", "-i", input_filename, "-filter_complex", filter, "-map", "[v]", "-map", "[a]",output_filename];
args ~= ["-filter_complex", filter, "-map", "[v]", "-map", "[a]", output_filename];
} else if (category == FileCategory.VIDEO) {
args = ["ffmpeg", "-loglevel", "warning", "-hide_banner", "-stats", "-i", input_filename, "-filter_complex", filter, "-map", "[v]", output_filename];
args ~= ["-filter_complex", filter, "-map", "[v]", output_filename];
} else if (category == FileCategory.AUDIO) {
args = ["ffmpeg", "-loglevel", "warning", "-hide_banner", "-stats", "-i", input_filename, "-filter_complex", filter, "-map", "[a]", output_filename];
args ~= ["-filter_complex", filter, "-map", "[a]", output_filename];
}
auto ffmpeg_process = spawnProcess(args);
return wait(ffmpeg_process) == 0;
Expand Down
10 changes: 9 additions & 1 deletion src/sponskrub/methods/chapter.d
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,18 @@ ClipChapterTime[] merge_sponsor_times_with_chapters(ClipTime[] sponsor_times, Ch
return clip_chapters;
}

string generate_chapter_title(ClipChapterTime chapter) {
if (chapter.category == Categories.Content) {
return chapter.title;
} else {
return chapter.title~" <"~chapter.category~">";
}
}

string generate_chapters_metadata(ClipChapterTime[] chapter_times) {
return ";FFMETADATA1\n" ~
chapter_times.map!(
x => format_chapter_metadata(x.start, x.end, x.title~x.category)
chapter => format_chapter_metadata(chapter.start, chapter.end, generate_chapter_title(chapter))
).join("\n");
}

Expand Down
20 changes: 16 additions & 4 deletions src/sponskrub/methods/cut.d
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,28 @@ import sponsorblock;
import ffwrap;
import chapter;

ClipTime[] timestamps_to_keep(ClipChapterTime[] chapters) {
//we can redo this so it just filters a bunch of chapter times and includes only content
ClipChapterTime[] timestamps_to_keep(ClipChapterTime[] chapters) {
return chapters
.sort!((a, b) => a.start.to!float < b.start.to!float)
.filter!(chapter => chapter.category == Categories.Content)
.map!(chapter => ClipTime(chapter.start, chapter.end, "")) //we need better types, this shouldn't need a category
.array;
}

string cut_and_cat_clips_filter(ClipTime[] timestamps, FileCategory category) {
ClipChapterTime[] calculate_timestamps_for_kept_clips(ClipChapterTime[] chapters) {
auto current_time = "0";
ClipChapterTime[] adjusted_chapters = [];

foreach (ClipChapterTime chapter; chapters) {
auto duration = chapter.end.to!float - chapter.start.to!float;
auto end_time = (current_time.to!float + duration).to!string; // I really need to deal with this bouncing between strings and floats nonsense
adjusted_chapters ~= ClipChapterTime(current_time, end_time, chapter.category, chapter.title);
current_time = end_time;
}
return adjusted_chapters;

}

string cut_and_cat_clips_filter(ClipChapterTime[] timestamps, FileCategory category) {
timestamps.sort!((a, b) => a.start.to!float < b.start.to!float);

auto clip_indexes = iota(0, timestamps.length);
Expand Down
9 changes: 4 additions & 5 deletions src/sponskrub/sponskrub.d
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ Options:
ClipChapterTime[] new_chapter_times;

chapter_times = get_chapter_times(input_filename);

if (chapter_times.length == 0) {
auto input_chapters_count = chapter_times.length;
if (input_chapters_count == 0) {
chapter_times = [ChapterTime("0", video_length, "sponskrub-content")];
}

Expand All @@ -161,16 +161,15 @@ Options:
generate_chapters_metadata(new_chapter_times)
);
} else {
//using the chapter data also means that in future we could also adjust
//preexisting chapter metadata to remain accurate after the cut
writeln("Surgically removing the shilling...");
auto content_times = timestamps_to_keep(new_chapter_times);

ffmpeg_status = run_ffmpeg_filter(
input_filename,
output_filename,
cut_and_cat_clips_filter(content_times, get_file_category(input_filename)),
get_file_category(input_filename)
get_file_category(input_filename),
generate_chapters_metadata(calculate_timestamps_for_kept_clips(content_times))
);
}

Expand Down

0 comments on commit 3fc04d9

Please sign in to comment.