ChapterForge
Loading...
Searching...
No Matches
chapter_timing.hpp
Go to the documentation of this file.
1//
2// chapter_timing.hpp
3// ChapterForge
4//
5// Created by Till Toenshoff on 12/9/25.
6// Copyright © 2025 Till Toenshoff. All rights reserved.
7//
8
9#pragma once
10#include <algorithm>
11#include <cstdint>
12#include <vector>
13
14#include "logging.hpp"
15
16// Derive durations (ms) from sorted start times. If total_ms > 0, the final
17// duration is clamped to fill the remaining time up to total_ms (min 1).
18template <typename Sample>
19inline std::vector<uint32_t> derive_durations_ms_from_starts(const std::vector<Sample> &samples,
20 uint32_t total_ms = 0) {
21 std::vector<uint32_t> durations;
22 durations.reserve(samples.size());
23 if (samples.empty()) {
24 return durations;
25 }
26 if (samples.front().start_ms != 0) {
27 // Apple players expect the first chapter to start at t=0. Warn callers so they
28 // can surface this to the user (e.g., log a warning).
29 CH_LOG("warn", "first chapter start_ms is " << samples.front().start_ms
30 << "ms; Apple players expect 0ms. "
31 << "Titles/URLs/thumbnails may not show.");
32 }
33 for (size_t i = 0; i < samples.size(); ++i) {
34 if (i + 1 < samples.size()) {
35 uint32_t cur = samples[i].start_ms;
36 uint32_t next = samples[i + 1].start_ms;
37 durations.push_back(next > cur ? (next - cur) : 1);
38 } else {
39 if (total_ms > 0 && samples[i].start_ms < total_ms) {
40 durations.push_back(std::max<uint32_t>(1, total_ms - samples[i].start_ms));
41 } else {
42 durations.push_back(1); // pad final sample with minimum duration
43 }
44 }
45 }
46 return durations;
47}
std::vector< uint32_t > derive_durations_ms_from_starts(const std::vector< Sample > &samples, uint32_t total_ms=0)
Definition chapter_timing.hpp:19
#define CH_LOG(level, message)
Definition logging.hpp:83