void PlayerComponent::handleMpvEvent(mpv_event *event) { switch (event->event_id) { case MPV_EVENT_START_FILE: { m_CurrentUrl = mpv::qt::get_property_variant(m_mpv, "path").toString(); m_playbackStartSent = false; break; } case MPV_EVENT_FILE_LOADED: { emit playing(m_CurrentUrl); break; } case MPV_EVENT_END_FILE: { mpv_event_end_file *end_file = (mpv_event_end_file *)event->data; switch (end_file->reason) { case MPV_END_FILE_REASON_EOF: emit finished(m_CurrentUrl); break; case MPV_END_FILE_REASON_ERROR: emit error(end_file->error, mpv_error_string(end_file->error)); break; default: emit stopped(m_CurrentUrl); break; } emit playbackEnded(m_CurrentUrl); m_CurrentUrl = ""; m_restoreDisplayTimer.start(0); break; } case MPV_EVENT_IDLE: { emit playbackAllDone(); break; } case MPV_EVENT_PLAYBACK_RESTART: { // it's also sent after seeks are completed if (!m_playbackStartSent) emit playbackStarting(); m_playbackStartSent = true; break; } case MPV_EVENT_PROPERTY_CHANGE: { mpv_event_property *prop = (mpv_event_property *)event->data; if (strcmp(prop->name, "pause") == 0 && prop->format == MPV_FORMAT_FLAG) { int state = *(int *)prop->data; emit paused(state); } else if (strcmp(prop->name, "cache-buffering-state") == 0 && prop->format == MPV_FORMAT_INT64) { int64_t percentage = *(int64_t *)prop->data; emit buffering(percentage); } else if (strcmp(prop->name, "playback-time") == 0 && prop->format == MPV_FORMAT_DOUBLE) { double pos = *(double*)prop->data; if (fabs(pos - m_lastPositionUpdate) > 0.25) { quint64 ms = (quint64)(qMax(pos * 1000.0, 0.0)); emit positionUpdate(ms); m_lastPositionUpdate = pos; } } else if (strcmp(prop->name, "vo-configured") == 0) { int state = prop->format == MPV_FORMAT_FLAG ? *(int *)prop->data : 0; emit windowVisible(state); } else if (strcmp(prop->name, "duration") == 0) { if (prop->format == MPV_FORMAT_DOUBLE) emit updateDuration(*(double *)prop->data * 1000.0); } else if (strcmp(prop->name, "audio-device-list") == 0) { updateAudioDeviceList(); } break; } case MPV_EVENT_LOG_MESSAGE: { mpv_event_log_message *msg = (mpv_event_log_message *)event->data; // Strip the trailing '\n' size_t len = strlen(msg->text); if (len > 0 && msg->text[len - 1] == '\n') len -= 1; QString logline = QString::fromUtf8(msg->prefix) + ": " + QString::fromUtf8(msg->text, len); if (msg->log_level >= MPV_LOG_LEVEL_V) QLOG_DEBUG() << qPrintable(logline); else if (msg->log_level >= MPV_LOG_LEVEL_INFO) QLOG_INFO() << qPrintable(logline); else if (msg->log_level >= MPV_LOG_LEVEL_WARN) QLOG_WARN() << qPrintable(logline); else QLOG_ERROR() << qPrintable(logline); break; } case MPV_EVENT_CLIENT_MESSAGE: { mpv_event_client_message *msg = (mpv_event_client_message *)event->data; // This happens when the player is about to load the file, but no actual loading has taken part yet. // We use this to block loading until we explicitly tell it to continue. if (msg->num_args >= 3 && !strcmp(msg->args[0], "hook_run") && !strcmp(msg->args[1], "1")) { QString resume_id = QString::fromUtf8(msg->args[2]); // Calling this lambda will instruct mpv to continue loading the file. auto resume = [=] { QLOG_INFO() << "resuming loading"; mpv::qt::command_variant(m_mpv, QStringList() << "hook-ack" << resume_id); }; if (switchDisplayFrameRate()) { // Now wait for some time for mode change - this is needed because mode changing can take some // time, during which the screen is black, and initializing hardware decoding could fail due // to various strange OS-related reasons. // (Better hope the user doesn't try to exit Konvergo during mode change.) int pause = SettingsComponent::Get().value(SETTINGS_SECTION_VIDEO, "refreshrate.delay").toInt() * 1000; QLOG_INFO() << "waiting" << pause << "msec after rate switch before loading"; QTimer::singleShot(pause, resume); } else { resume(); } break; } } default:; /* ignore */ } }
void DesktopSelectionWindow::hideEvent(QHideEvent * hideEvt) { QWidget::hideEvent(hideEvt); emit windowVisible(false); }