]> git.sesse.net Git - pkanalytics/blob - stats.cpp
Factor out timestamp formatting.
[pkanalytics] / stats.cpp
1 #include <QMediaPlayer>
2 #include <QMainWindow>
3 #include <QApplication>
4 #include <QGridLayout>
5 #include <QVideoWidget>
6 #include <QShortcut>
7 #include <string>
8 #include <sqlite3.h>
9 #include "mainwindow.h"
10 #include "ui_mainwindow.h"
11
12 std::string format_timestamp(uint64_t pos)
13 {
14         int ms = pos % 1000;
15         pos /= 1000;
16         int sec = pos % 60;
17         pos /= 60;
18         int min = pos % 60;
19         int hour = pos / 60;
20
21         char buf[256];
22         snprintf(buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms);
23         return buf;
24 }
25
26 MainWindow::MainWindow()
27 {
28         player = new QMediaPlayer;
29         //player->setSource(QUrl::fromLocalFile("/home/sesse/dev/stats/ultimate.mkv"));
30         player->setSource(QUrl::fromLocalFile("/home/sesse/dev/stats/ultimate-prores.mkv"));
31         player->play();
32
33         Ui::MainWindow *ui = new Ui::MainWindow;
34         ui->setupUi(this);
35
36         connect(player, &QMediaPlayer::positionChanged, [ui, this](uint64_t pos) {
37                 ui->timestamp->setText(QString::fromUtf8(format_timestamp(pos)));
38                 if (buffered_seek) {
39                         player->setPosition(*buffered_seek);
40                         buffered_seek.reset();
41                 }
42                 if (!playing) {
43                         player->pause();  // We only played to get a picture.
44                 }
45         });
46
47         player->setVideoOutput(ui->video);
48
49         QShortcut *key_k = new QShortcut(QKeySequence(Qt::Key_K), this);
50         connect(key_k, &QShortcut::activated, [this]() { seek(-10000); });
51
52         QShortcut *key_l = new QShortcut(QKeySequence(Qt::Key_L), this);
53         connect(key_l, &QShortcut::activated, [this]() { seek(10000); });
54
55         QShortcut *key_left = new QShortcut(QKeySequence(Qt::Key_Left), this);
56         connect(key_left, &QShortcut::activated, [this]() { seek(-1000); });
57
58         QShortcut *key_right = new QShortcut(QKeySequence(Qt::Key_Right), this);
59         connect(key_right, &QShortcut::activated, [this]() { seek(1000); });
60
61         // TODO: Would be nice to actually have a frame...
62         QShortcut *key_comma = new QShortcut(QKeySequence(Qt::Key_Comma), this);
63         connect(key_comma, &QShortcut::activated, [this]() { seek(-20); });
64
65         QShortcut *key_period = new QShortcut(QKeySequence(Qt::Key_Period), this);
66         connect(key_period, &QShortcut::activated, [this]() { seek(20); });
67
68         QShortcut *key_space = new QShortcut(QKeySequence(Qt::Key_Space), this);
69         connect(key_space, &QShortcut::activated, [this]() {
70                 if (playing) {
71                         player->pause();
72                 } else {
73                         player->setPlaybackRate(1.0);
74                         player->play();
75                 }
76                 playing = !playing;
77         });
78 }
79
80 void MainWindow::seek(int64_t delta_ms)
81 {
82         int64_t current_pos = buffered_seek ? *buffered_seek : player->position();
83         uint64_t pos = std::max<int64_t>(current_pos + delta_ms, 0);
84         buffered_seek = pos;
85         if (!playing) {
86                 player->setPlaybackRate(0.01);
87                 player->play();  // Or Qt won't show the seek.
88         }
89 }
90
91 int main(int argc, char *argv[])
92 {
93         QApplication app(argc, argv);
94
95         MainWindow mainWindow;
96         mainWindow.resize(QSize(1280, 720));
97         mainWindow.show();
98
99         return app.exec();
100
101 }