summaryrefslogtreecommitdiffstats
path: root/kaffeine/src/player-parts/libmpv-part/libmpv_event.cpp
blob: f6edbecf0f39de99463d33215be27fafbbea4e02 (plain)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * Kaffeine libmpv part
 * Copyright (C) 2023 Mavridis Philippe <[email protected]>
 *
 * Based on Kaffeine dummy part
 * Copyright (C) 2004-2005 Jürgen Kofler <[email protected]>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 */

// TQt
#include <tqapplication.h>

// TDE
#include <tdelocale.h>
#include <kdebug.h>

// Part
#include "libmpv_event.h"
#include "libmpv_part.h"

MpvEventThread::MpvEventThread(MpvPart *part) {
    m_part = part;
    initPropertyObservers();
}

void MpvEventThread::initPropertyObservers() {
    mpv_observe_property(m_part->m_mpv, 0, "time-pos",    MPV_FORMAT_DOUBLE);
    mpv_observe_property(m_part->m_mpv, 0, "duration",    MPV_FORMAT_DOUBLE);
    mpv_observe_property(m_part->m_mpv, 0, "media-title", MPV_FORMAT_STRING);

    // "The advantage over using this instead of calculating it out of other
    // properties is that it properly falls back to estimating the playback
    // position from the byte position, if the file duration is not known."
    mpv_observe_property(m_part->m_mpv, 0, "percent-pos", MPV_FORMAT_DOUBLE);

    //mpv_observe_property(m_mpv, 0, "track-list", MPV_FORMAT_NODE);
    //mpv_observe_property(m_mpv, 0, "chapter-list", MPV_FORMAT_NODE);
}

void MpvEventThread::run() {
    while (m_part->m_mpv) {
        mpv_event *event = mpv_wait_event(m_part->m_mpv, 0);
        if (event->event_id != MPV_EVENT_NONE) {
            processEvent(event);
        }
    }
}

void MpvEventThread::processEvent(mpv_event *event) {
    switch (event->event_id) {
        case MPV_EVENT_PROPERTY_CHANGE: {
            mpv_event_property *prop = (mpv_event_property *)event->data;
            MpvPropertyChangeEvent *pe = new MpvPropertyChangeEvent(
                prop->name, prop->format, prop->data);
            TQApplication::postEvent(m_part, pe);
            break;
        }

        case MPV_EVENT_LOG_MESSAGE: {
            struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data;
            kdDebug() << "[mpv " << msg->prefix << "] <" << msg->level << ">: "
                      << msg->text << endl;

            m_part->setStatusBarText(TQString("MPV %1 (%2): %3").arg(msg->prefix, msg->level, msg->text));

            if (TQString(msg->level) == "error") {
                processErrorMessage(msg->prefix, msg->level, msg->text);
            }
            break;
        }

        case MPV_EVENT_END_FILE: {
            struct mpv_event_end_file *end = (struct mpv_event_end_file *)event->data;
            TQString error;
            if (end->reason == MPV_END_FILE_REASON_ERROR) {
                error = TQString(mpv_error_string(end->error));
            }
            MpvEOFEvent *eofe = new MpvEOFEvent(end->reason, error);
            TQApplication::postEvent(m_part, eofe);
        }

        default: break; // ignore other events
    }
}

void MpvEventThread::processErrorMessage(TQString prefix, TQString level, TQString text) {
    if (prefix == "recorder") {
        kdDebug() << "recorder error:" << text << endl;
        MpvErrorEvent *ee = new MpvErrorEvent(
            i18n("An error occurred in the stream recorder."),
            i18n("Recording error"), text
        );
        TQApplication::postEvent(m_part, ee);
        m_part->stopRecording();
    }
}