forked from nu774/qaac
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathchapters.cpp
More file actions
71 lines (66 loc) · 2.61 KB
/
chapters.cpp
File metadata and controls
71 lines (66 loc) · 2.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <cstdio>
#include "chapters.h"
#include "strutil.h"
#include "textfile.h"
namespace chapters {
void add_entry(std::vector<abs_entry_t> &chapters,
const wchar_t *name,
int h, int m, double s)
{
std::wstring sname = name ? name : L"";
double stamp = ((h * 60) + m) * 60 + s;
if (!chapters.size() && stamp != 0.0)
throw std::runtime_error("Non zero timestamp on the first chapter "
"entry is not acceptable");
else if (chapters.size()) {
abs_entry_t &prev = chapters.back();
if (prev.second >= stamp)
throw std::runtime_error("Chapter timestamps is required to "
"be strictly increasing");
}
chapters.push_back(std::make_pair(sname, stamp));
}
void load_from_file(const std::wstring &path,
std::vector<abs_entry_t> *chapters,
uint32_t codepage)
{
std::vector<abs_entry_t> chaps;
std::wstring str = load_text_file(path, codepage);
const wchar_t *tfmt = L"%02d:%02d:%lf";
int h = 0, m = 0;
double s = 0.0;
strutil::Tokenizer<wchar_t> tokens(str, L"\n");
wchar_t *tok;
while ((tok = tokens.next())) {
if (*tok && tok[0] == L'#')
continue;
if (std::swscanf(tok, tfmt, &h, &m, &s) == 3) {
strutil::strsep(&tok, L"\t ");
add_entry(chaps, tok, h, m, s);
} else if (wcsncmp(tok, L"Chapter", 7) == 0) {
int hh, mm;
double ss;
wchar_t *key = strutil::strsep(&tok, L"=");
if (std::wcsstr(key, L"NAME"))
add_entry(chaps, tok, h, m, s);
else if (std::swscanf(tok, tfmt, &hh, &mm, &ss) == 3)
h = hh, m = mm, s = ss;
}
}
chapters->swap(chaps);
}
void abs_to_duration(const std::vector<abs_entry_t> abs_ents,
std::vector<entry_t> *dur_ents,
double total_duration)
{
std::vector<entry_t> chapters;
// convert from absolute timestamp to duration
for (size_t i = 0; i < abs_ents.size(); ++i) {
double end = (i == abs_ents.size() - 1) ? total_duration
: abs_ents[i+1].second;
double span = end - abs_ents[i].second;
chapters.push_back(std::make_pair(abs_ents[i].first, span));
}
dur_ents->swap(chapters);
}
}