admin管理员组

文章数量:1279247

I am working on a project to display videos on the desktop wallpaper but SetDeskWallpaper isn't fast enough and is too hard to sync music with it. I tried vlc, turns out you can't install their sdk anymore or you never could in the first place soo that's useless.

My current attempt is to use media foundation, but I get the error you can see below.

I need to display the video on the wallpaper (including audio).
I need it to run on windows 11
I need it to work in 2025
I need it to be c++ code
I need it to be compatible with Visual Studio 2022
I am also looking for alternatives to my current script because ai is a complete and utter lie

The code:

#include <mfapi.h>
#include <mfidl.h>
#include <mfobjects.h>
#include <mfplay.h>
#include <mferror.h>
#include <mfreadwrite.h>
#include <propvarutil.h>
#include <windows.h>
#include <iostream>

#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfuuid.lib")
#pragma comment(lib, "mfreadwrite.lib")
#pragma comment(lib, "mfplay.lib")

// Define a custom window procedure to handle video rendering window
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int main()
{
    // Initialize COM and Media Foundation
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        std::cout << "CoInitializeEx failed with error " << hr << std::endl;
        return -1;
    }

    hr = MFStartup(MF_VERSION);
    if (FAILED(hr)) {
        std::cout << "MFStartup failed with error " << hr << std::endl;
        CoUninitialize();
        return -1;
    }

    // Create the media source
    IMFSourceResolver* pSourceResolver = NULL;
    IUnknown* pSource = NULL;
    IMFMediaSource* pMediaSource = NULL;
    hr = MFCreateSourceResolver(&pSourceResolver);
    if (FAILED(hr)) {
        std::cout << "MFCreateSourceResolver failed with error " << hr << std::endl;
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    MF_OBJECT_TYPE objectType = MF_OBJECT_INVALID;
    hr = pSourceResolver->CreateObjectFromURL(
        L"C:\\Users\\username\\Downloads\\video.webm",
        MF_RESOLUTION_MEDIASOURCE,
        NULL,
        &objectType,
        &pSource);

    if (FAILED(hr)) {
        std::cout << "CreateObjectFromURL failed with error " << hr << std::endl;
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    hr = pSource->QueryInterface(IID_PPV_ARGS(&pMediaSource));
    if (FAILED(hr)) {
        std::cout << "QueryInterface failed with error " << hr << std::endl;
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    // Create a Media Session for playback
    IMFAttributes* pAttributes = NULL;
    IMFMediaSession* pMediaSession = NULL;
    hr = MFCreateAttributes(&pAttributes, 1);
    if (FAILED(hr)) {
        std::cout << "MFCreateAttributes failed with error " << hr << std::endl;
        pMediaSource->Release();
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    hr = MFCreateMediaSession(pAttributes, &pMediaSession);
    if (FAILED(hr)) {
        std::cout << "MFCreateMediaSession failed with error " << hr << std::endl;
        pAttributes->Release();
        pMediaSource->Release();
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    // Setup for video rendering
    HWND hwnd = CreateWindowEx(0, L"STATIC", L"Video Player", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
        NULL, NULL, NULL, NULL);

    if (!hwnd) {
        std::cout << "Failed to create window" << std::endl;
        pMediaSession->Release();
        pAttributes->Release();
        pMediaSource->Release();
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    // Fullscreen the window to cover the desktop
    ShowWindow(hwnd, SW_MAXIMIZE);

    // At this point, you would add rendering logic for the video using Media Foundation video display interfaces

    // Start playback, render video to window, and loop until user closes the window

    // Cleanup
    if (pMediaSession) pMediaSession->Release();
    if (pAttributes) pAttributes->Release();
    if (pMediaSource) pMediaSource->Release();
    if (pSource) pSource->Release();
    if (pSourceResolver) pSourceResolver->Release();
    MFShutdown();
    CoUninitialize();

    return 0;
}

The error I get:

Error   LNK2019 unresolved external symbol MFCreateMediaSession 
referenced in function main Test    C:
\Users\username\source\repos\Test\Test\main.obj 1       

I am working on a project to display videos on the desktop wallpaper but SetDeskWallpaper isn't fast enough and is too hard to sync music with it. I tried vlc, turns out you can't install their sdk anymore or you never could in the first place soo that's useless.

My current attempt is to use media foundation, but I get the error you can see below.

I need to display the video on the wallpaper (including audio).
I need it to run on windows 11
I need it to work in 2025
I need it to be c++ code
I need it to be compatible with Visual Studio 2022
I am also looking for alternatives to my current script because ai is a complete and utter lie

The code:

#include <mfapi.h>
#include <mfidl.h>
#include <mfobjects.h>
#include <mfplay.h>
#include <mferror.h>
#include <mfreadwrite.h>
#include <propvarutil.h>
#include <windows.h>
#include <iostream>

#pragma comment(lib, "mfplat.lib")
#pragma comment(lib, "mfuuid.lib")
#pragma comment(lib, "mfreadwrite.lib")
#pragma comment(lib, "mfplay.lib")

// Define a custom window procedure to handle video rendering window
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    if (uMsg == WM_DESTROY)
    {
        PostQuitMessage(0);
        return 0;
    }
    return DefWindowProc(hwnd, uMsg, wParam, lParam);
}

int main()
{
    // Initialize COM and Media Foundation
    HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    if (FAILED(hr)) {
        std::cout << "CoInitializeEx failed with error " << hr << std::endl;
        return -1;
    }

    hr = MFStartup(MF_VERSION);
    if (FAILED(hr)) {
        std::cout << "MFStartup failed with error " << hr << std::endl;
        CoUninitialize();
        return -1;
    }

    // Create the media source
    IMFSourceResolver* pSourceResolver = NULL;
    IUnknown* pSource = NULL;
    IMFMediaSource* pMediaSource = NULL;
    hr = MFCreateSourceResolver(&pSourceResolver);
    if (FAILED(hr)) {
        std::cout << "MFCreateSourceResolver failed with error " << hr << std::endl;
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    MF_OBJECT_TYPE objectType = MF_OBJECT_INVALID;
    hr = pSourceResolver->CreateObjectFromURL(
        L"C:\\Users\\username\\Downloads\\video.webm",
        MF_RESOLUTION_MEDIASOURCE,
        NULL,
        &objectType,
        &pSource);

    if (FAILED(hr)) {
        std::cout << "CreateObjectFromURL failed with error " << hr << std::endl;
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    hr = pSource->QueryInterface(IID_PPV_ARGS(&pMediaSource));
    if (FAILED(hr)) {
        std::cout << "QueryInterface failed with error " << hr << std::endl;
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    // Create a Media Session for playback
    IMFAttributes* pAttributes = NULL;
    IMFMediaSession* pMediaSession = NULL;
    hr = MFCreateAttributes(&pAttributes, 1);
    if (FAILED(hr)) {
        std::cout << "MFCreateAttributes failed with error " << hr << std::endl;
        pMediaSource->Release();
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    hr = MFCreateMediaSession(pAttributes, &pMediaSession);
    if (FAILED(hr)) {
        std::cout << "MFCreateMediaSession failed with error " << hr << std::endl;
        pAttributes->Release();
        pMediaSource->Release();
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    // Setup for video rendering
    HWND hwnd = CreateWindowEx(0, L"STATIC", L"Video Player", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
        0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
        NULL, NULL, NULL, NULL);

    if (!hwnd) {
        std::cout << "Failed to create window" << std::endl;
        pMediaSession->Release();
        pAttributes->Release();
        pMediaSource->Release();
        pSource->Release();
        pSourceResolver->Release();
        MFShutdown();
        CoUninitialize();
        return -1;
    }

    // Fullscreen the window to cover the desktop
    ShowWindow(hwnd, SW_MAXIMIZE);

    // At this point, you would add rendering logic for the video using Media Foundation video display interfaces

    // Start playback, render video to window, and loop until user closes the window

    // Cleanup
    if (pMediaSession) pMediaSession->Release();
    if (pAttributes) pAttributes->Release();
    if (pMediaSource) pMediaSource->Release();
    if (pSource) pSource->Release();
    if (pSourceResolver) pSourceResolver->Release();
    MFShutdown();
    CoUninitialize();

    return 0;
}

The error I get:

Error   LNK2019 unresolved external symbol MFCreateMediaSession 
referenced in function main Test    C:
\Users\username\source\repos\Test\Test\main.obj 1       
Share Improve this question edited Feb 24 at 16:37 wohlstad 29.2k16 gold badges59 silver badges91 bronze badges asked Feb 24 at 14:30 user29779116user29779116 293 bronze badges 4
  • Let me share my method of making dynamic wallpaper: 1. Create a window, or directly use a window (such as chorme), and then play the content I want on it. 2. Make the window a window without hit testing, that is, all input will penetrate the underlying window, and then push it to the bottom of the Z order. 3. Create a layered window (again without hit testing), make all pixels that are the same color as the desktop background transparent, and then periodically copy the image of the desktop to this window. 4. Place the layered window above the window that plays the video. – 許恩嘉 Commented Feb 24 at 15:03
  • sounds pretty cool and sorta simple but i have had a really rough experience with windows and DC's in the past soo imma probs just keep looking for something open source i can implement. – user29779116 Commented Feb 24 at 15:46
  • It looks like you're working on a way to play the video. But how are you going to make it appear on the desktop without covering up the icons? You'd better solve this problem first, and then worry about how to render your window. – 許恩嘉 Commented Feb 25 at 2:58
  • yeah i got it to semi work with opencv2 but it flickers lol. – user29779116 Commented Feb 25 at 13:11
Add a comment  | 

1 Answer 1

Reset to default 0

Your error is a linker error.

As you can see in the MFCreateMediaSession documentation,
you need to link with Mf.lib.

In VS2022 this can be done by opening project properties -> Linker -> Input, then add Mf.lib in Additional Dependencies.

Alternatively, you can link the library by adding a #pragma in one of the sources:

#pragma comment(lib, "mf.lib")

本文标签: cProblem displaying wallpaper video using media foundationStack Overflow