From 378547d7c18e75c2145af57afda2a8b96a609bfa Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Sun, 30 Apr 2023 12:27:27 +0200 Subject: [PATCH] Initial commit; really only a (bad) video player. --- mainwindow.h | 21 ++++++++++++ mainwindow.ui | 66 +++++++++++++++++++++++++++++++++++ meson.build | 10 ++++++ stats.cpp | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 192 insertions(+) create mode 100644 mainwindow.h create mode 100644 mainwindow.ui create mode 100644 meson.build create mode 100644 stats.cpp diff --git a/mainwindow.h b/mainwindow.h new file mode 100644 index 0000000..052e15d --- /dev/null +++ b/mainwindow.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include + +class MainWindow : public QMainWindow +{ + Q_OBJECT + +public: + MainWindow(); + + QMediaPlayer *player; + +private: + void seek(int64_t delta_ms); + bool seeking = false; + bool playing = true; + std::optional buffered_seek; +}; diff --git a/mainwindow.ui b/mainwindow.ui new file mode 100644 index 0000000..a64b1e3 --- /dev/null +++ b/mainwindow.ui @@ -0,0 +1,66 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + + + + 1:02:03 + + + + + + + + 320 + 240 + + + + + + + + + + + + + + + 0 + 0 + 800 + 23 + + + + + + + + QVideoWidget + QWidget +
QVideoWidget
+ 1 +
+
+ + +
diff --git a/meson.build b/meson.build new file mode 100644 index 0000000..4df5b37 --- /dev/null +++ b/meson.build @@ -0,0 +1,10 @@ +project('stats', 'cpp', default_options: ['buildtype=debugoptimized'], version: '0.0.1') + +qt6 = import('qt6') +qt6deps = dependency('qt6', modules: ['Core', 'Gui', 'Widgets', 'Multimedia', 'MultimediaWidgets']) +qt_files = qt6.preprocess( + moc_headers: ['mainwindow.h'], + ui_files: ['mainwindow.ui'], + dependencies: qt6deps) + +executable('stats', 'stats.cpp', qt_files, dependencies: [qt6deps]) diff --git a/stats.cpp b/stats.cpp new file mode 100644 index 0000000..7bce2a2 --- /dev/null +++ b/stats.cpp @@ -0,0 +1,95 @@ +#include +#include +#include +#include +#include +#include +#include +#include "mainwindow.h" +#include "ui_mainwindow.h" + +MainWindow::MainWindow() +{ + player = new QMediaPlayer; + //player->setSource(QUrl::fromLocalFile("/home/sesse/dev/stats/ultimate.mkv")); + player->setSource(QUrl::fromLocalFile("/home/sesse/dev/stats/ultimate-prores.mkv")); + player->play(); + + Ui::MainWindow *ui = new Ui::MainWindow; + ui->setupUi(this); + + connect(player, &QMediaPlayer::positionChanged, [ui, this](uint64_t pos) { + int ms = pos % 1000; + pos /= 1000; + int sec = pos % 60; + pos /= 60; + int min = pos % 60; + int hour = pos / 60; + + char buf[256]; + snprintf(buf, sizeof(buf), "%d:%02d:%02d.%03d", hour, min, sec, ms); + ui->timestamp->setText(buf); + if (buffered_seek) { + player->setPosition(*buffered_seek); + buffered_seek.reset(); + } + if (!playing) { + player->pause(); // We only played to get a picture. + } + }); + + player->setVideoOutput(ui->video); + + QShortcut *key_k = new QShortcut(QKeySequence(Qt::Key_K), this); + connect(key_k, &QShortcut::activated, [this]() { seek(-10000); }); + + QShortcut *key_l = new QShortcut(QKeySequence(Qt::Key_L), this); + connect(key_l, &QShortcut::activated, [this]() { seek(10000); }); + + QShortcut *key_left = new QShortcut(QKeySequence(Qt::Key_Left), this); + connect(key_left, &QShortcut::activated, [this]() { seek(-1000); }); + + QShortcut *key_right = new QShortcut(QKeySequence(Qt::Key_Right), this); + connect(key_right, &QShortcut::activated, [this]() { seek(1000); }); + + // TODO: Would be nice to actually have a frame... + QShortcut *key_comma = new QShortcut(QKeySequence(Qt::Key_Comma), this); + connect(key_comma, &QShortcut::activated, [this]() { seek(-20); }); + + QShortcut *key_period = new QShortcut(QKeySequence(Qt::Key_Period), this); + connect(key_period, &QShortcut::activated, [this]() { seek(20); }); + + QShortcut *key_space = new QShortcut(QKeySequence(Qt::Key_Space), this); + connect(key_space, &QShortcut::activated, [this]() { + if (playing) { + player->pause(); + } else { + player->setPlaybackRate(1.0); + player->play(); + } + playing = !playing; + }); +} + +void MainWindow::seek(int64_t delta_ms) +{ + int64_t current_pos = buffered_seek ? *buffered_seek : player->position(); + uint64_t pos = std::max(current_pos + delta_ms, 0); + buffered_seek = pos; + if (!playing) { + player->setPlaybackRate(0.01); + player->play(); // Or Qt won't show the seek. + } +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + + MainWindow mainWindow; + mainWindow.resize(QSize(1280, 720)); + mainWindow.show(); + + return app.exec(); + +} -- 2.39.2