1
0

mpv event

This commit is contained in:
2024-11-21 00:33:02 +08:00
parent 05b756efde
commit 0d57ac21ed
2 changed files with 54 additions and 16 deletions

View File

@@ -20,12 +20,13 @@
"name": "MinGW64",
"includePath": [
"${workspaceFolder}/**",
"D:\\msys64\\mingw64\\include"
"C:/MinGW64/include",
"C:/MinGW64/x86_64-w64-mingw32/include/**"
],
"defines": [
"USE_OPENGL"
],
"compilerPath": "D:\\msys64\\mingw64\\bin\\gcc.exe",
"compilerPath": "C:/MinGW64/bin/gcc.exe",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "windows-gcc-x64"

View File

@@ -2,7 +2,7 @@
#include <cstdlib>
#include <mpv/client.h>
#include <mpv/render.h>
#include <mpv/render_dxgi.h>
#include <imgui_impl_win32.h>
#include <imgui_impl_dx11.h>
@@ -18,6 +18,7 @@ static ID3D11DeviceContext* d3dDeviceContext = nullptr;
static IDXGISwapChain* d3dSwapChain = nullptr;
static ID3D11RenderTargetView* d3dRenderTargetView = nullptr;
static HWND hwnd = nullptr;
static mpv_handle* mpv = nullptr;
static int osdShow = 0;
// Forward declarations of helper functions
@@ -35,8 +36,6 @@ static int64_t mpv_property_int(mpv_handle* mpv, const char* key) {
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true;
switch (msg) {
case WM_SIZE:
if (wParam == SIZE_MINIMIZED) return 0;
@@ -48,11 +47,46 @@ LRESULT WINAPI wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
break;
case WM_KEYUP:
if (wParam == VK_RETURN) osdShow = !osdShow;
else if (wParam == VK_SPACE) mpv_command_string(mpv, "set pause yes");
break;
case WM_USER:
while (true) {
mpv_event* mp_event = mpv_wait_event(mpv, 0);
if (mp_event->event_id == MPV_EVENT_NONE) {
break;
} else if (mp_event->event_id == MPV_EVENT_START_FILE) {
printf("MPV => START FILE\n");
} else if (mp_event->event_id == MPV_EVENT_FILE_LOADED) {
printf("MPV => FILE LOADED\n");
} else if (mp_event->event_id == MPV_EVENT_PLAYBACK_RESTART) {
printf("MPV => PLAYBACK RESTART\n");
} else if (mp_event->event_id == MPV_EVENT_COMMAND_REPLY) {
if (mp_event->error) {
printf("MPV => COMMAND ERROR: %s\n", mpv_error_string(mp_event->error));
break;
}
} else if (mp_event->event_id == MPV_EVENT_END_FILE) {
auto node = (mpv_event_end_file*)mp_event->data;
if (node->reason == MPV_END_FILE_REASON_ERROR) {
printf("MPV => FILE ERROR: %s\n", mpv_error_string(node->error));
} else if (node->reason == MPV_END_FILE_REASON_EOF) {
printf("MPV => END_OF_FILE\n");
} else {
printf("MPV => STOP\n");
}
return 0;
} else if (mp_event->event_id == MPV_EVENT_PROPERTY_CHANGE) {
/// https://mpv.io/manual/stable/#property-list
mpv_event_property* prop = (mpv_event_property*)mp_event->data;
printf("MPV => PROPERTY `%s` type %d\n", prop->name, int(prop->format));
}
}
break;
case WM_DESTROY:
::PostQuitMessage(0);
return 0;
}
if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true;
return ::DefWindowProcW(hWnd, msg, wParam, lParam);
}
@@ -67,39 +101,40 @@ int main(int argc, char* argv[]) {
wc.lpszClassName = L"MpvClass";
if (!RegisterClassExW(&wc)) die("register class failed");
hwnd = CreateWindowExW(0, wc.lpszClassName, L"xplayer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1280, 720,
nullptr, nullptr, wc.hInstance, nullptr);
hwnd = CreateWindowExW(0, wc.lpszClassName, L"xplayer", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 1280,
720, nullptr, nullptr, wc.hInstance, nullptr);
if (!hwnd) die("create window failed");
if (!InitD3D(hwnd)) die("init dx11 failed");
mpv_render_context* mpv_context = nullptr;
mpv_handle* mpv = mpv_create();
mpv = mpv_create();
mpv_set_option_string(mpv, "subs-fallback", "yes");
mpv_set_option_string(mpv, "video-timing-offset", "0"); // 60fps
mpv_set_option_string(mpv, "vd-lavc-dr", "yes");
mpv_set_option_string(mpv, "terminal", "yes");
// mpv_set_option_string(mpv, "terminal", "yes");
mpv_set_option_string(mpv, "ytdl", "no");
mpv_set_option_string(mpv, "hwdec", "auto");
mpv_set_option_string(mpv, "vo", "gpu-next");
mpv_set_option_string(mpv, "msg-level", "all=v");
mpv_set_option(mpv, "wid", MPV_FORMAT_INT64, &hwnd);
mpv_set_option(mpv, "d3d11-device", MPV_FORMAT_INT64, &d3dDevice);
mpv_set_option_string(mpv, "vo", "libmpv");
if (mpv_initialize(mpv) < 0) die("init mpv failed");
mpv_dxgi_init_params init_params = {d3dDevice, d3dSwapChain};
mpv_render_param params[] = {
{MPV_RENDER_PARAM_API_TYPE, (void*)MPV_RENDER_API_TYPE_SW},
{MPV_RENDER_PARAM_INVALID, nullptr},
{MPV_RENDER_PARAM_API_TYPE, const_cast<char *>(MPV_RENDER_API_TYPE_DXGI)},
{MPV_RENDER_PARAM_DXGI_INIT_PARAMS, &init_params},
{MPV_RENDER_PARAM_INVALID, NULL},
};
if (mpv_render_context_create(&mpv_context, mpv, params) < 0) die("init mpv context failed");
mpv_render_context_set_update_callback(
mpv_context,
[](void* obj) {
mpv_render_context* ctx = static_cast<mpv_render_context*>(obj);
uint64_t flags = mpv_render_context_update(ctx);
if (flags & MPV_RENDER_UPDATE_FRAME) PostMessage(hwnd, WM_NULL, 0, 0);
if (flags & MPV_RENDER_UPDATE_FRAME) PostMessage(hwnd, WM_PAINT, 0, 0);
},
mpv_context);
mpv_set_wakeup_callback(mpv, [](void* obj) { PostMessage(hwnd, WM_USER, 0L, (LPARAM)obj); }, mpv);
// Show the window
::ShowWindow(hwnd, SW_SHOWDEFAULT);
@@ -159,6 +194,8 @@ int main(int argc, char* argv[]) {
d3dDeviceContext->OMSetRenderTargets(1, &d3dRenderTargetView, nullptr);
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
ImGui::EndFrame();
d3dSwapChain->Present(1, 0); // Present with vsync
}