Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new way to use custom http headers #7

Open
TSCSOftware opened this issue Mar 10, 2023 · 3 comments
Open

new way to use custom http headers #7

TSCSOftware opened this issue Mar 10, 2023 · 3 comments

Comments

@TSCSOftware
Copy link

`HRESULT OpenURL(const std::wstring& url) override {
HRESULT hr = S_OK;
wil::com_ptr resolver;
wil::com_ptr source;
wil::com_ptr mediaSource;
wil::com_ptr presentationDescriptor;

// Create the source resolver.
hr = MFCreateSourceResolver(&resolver);
if (!SUCCEEDED(hr)) {
std::cout << "MFCreateSourceResolver failed: " << hr << std::endl;
return hr;
}

// Set custom headers on the resolver.
if (!headers.empty()) {
wil::com_ptr credentialManager;
hr = MFCreateCredentialManager(&credentialManager);
if (SUCCEEDED(hr)) {
wil::com_ptr resolverAttributes;
hr = MFCreateAttributes(&resolverAttributes, 1);
if (SUCCEEDED(hr)) {
hr = resolverAttributes->SetUnknown(MFNETSOURCE_CREDENTIAL_MANAGER, credentialManager.get());
if (SUCCEEDED(hr)) {
for (const auto& header : headers) {
hr = resolverAttributes->SetString(MFNETSOURCE_HTTP_REQUEST_HEADERS, (LPCWSTR)header.first.c_str(), (LPCWSTR)header.second.c_str());
if (!SUCCEEDED(hr)) {
std::cout << "Failed to set header: " << header.first << std::endl;
}
}
}
}
}
if (!SUCCEEDED(hr)) {
std::cout << "Failed to set credentials manager" << std::endl;
return hr;
}
}

// Use the resolver to create a media source.
hr = resolver->CreateObjectFromURL(url.c_str(), MF_RESOLUTION_MEDIASOURCE, nullptr, &source);
if (!SUCCEEDED(hr)) {
std::cout << "CreateObjectFromURL failed: " << hr << std::endl;
return hr;
}

hr = source->QueryInterface(IID_PPV_ARGS(&mediaSource));
if (!SUCCEEDED(hr)) {
std::cout << "QueryInterface for IMFMediaSource failed: " << hr << std::endl;
return hr;
}

// Create a presentation descriptor for the media source.
hr = mediaSource->CreatePresentationDescriptor(&presentationDescriptor);
if (!SUCCEEDED(hr)) {
std::cout << "CreatePresentationDescriptor failed: " << hr << std::endl;
return hr;
}

// ... existing code ...
}
`

`IMFMediaSource* pSource = NULL;
IMFSourceResolver* pSourceResolver = NULL;
HRESULT hr = MFCreateSourceResolver(&pSourceResolver);
if (FAILED(hr))
{
// Handle error
}

// Create a property store to hold the HTTP headers
IPropertyStore* pPropertyStore = NULL;
hr = MFCreatePropertyStore(&pPropertyStore);
if (FAILED(hr))
{
// Handle error
}

// Set the custom HTTP headers
PROPVARIANT var;
PropVariantInit(&var);
var.vt = VT_BSTR;
var.bstrVal = SysAllocString(L"Authorization: Bearer TOKEN");
hr = pPropertyStore->SetValue(MF_HTTP_REQUEST_HEADERS, var);
if (FAILED(hr))
{
// Handle error
}

// Create a property store to hold the URL
PROPVARIANT varURL;
PropVariantInit(&varURL);
varURL.vt = VT_BSTR;
varURL.bstrVal = SysAllocString(L"http://example.com/video.mp4");

// Create the media source
MF_OBJECT_TYPE ObjectType = MF_OBJECT_INVALID;
hr = pSourceResolver->CreateObjectFromURL(varURL.bstrVal, MF_RESOLUTION_MEDIASOURCE, pPropertyStore, &ObjectType, (IUnknown**)&pSource);
if (FAILED(hr))
{
// Handle error
}

// Cleanup
PropVariantClear(&var);
PropVariantClear(&varURL);
SafeRelease(&pSourceResolver);
SafeRelease(&pPropertyStore);`

`#include "windows_media_player.h"

#include
#include
#include

#include <winrt/Windows.Foundation.Collections.h>
#include <winrt/Windows.Media.Core.h>
#include <winrt/Windows.Media.Playback.h>
#include <winrt/Windows.Storage.h>
#include <winrt/Windows.Web.Http.Headers.h>

namespace {

std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;

}

WindowsMediaPlayer::WindowsMediaPlayer() = default;

WindowsMediaPlayer::~WindowsMediaPlayer() = default;

void WindowsMediaPlayer::CreateMediaSource(
const std::string& uri, const std::map<std::string, std::string>& headers, winrt::Windows::Media::Core::MediaSource& media_source) const {
auto w_uri = converter.from_bytes(uri);
auto uri_obj = winrt::Windows::Foundation::Uri(w_uri);

winrt::Windows::Web::Http::Headers::HttpRequestHeaderCollection header_collection;
for (const auto& [key, value] : headers) {
auto w_key = converter.from_bytes(key);
auto w_value = converter.from_bytes(value);
header_collection.TryAppendWithoutValidation(w_key, w_value);
}

winrt::Windows::Web::Http::HttpClient client;
client.DefaultRequestHeaders().InsertRange(header_collection);

auto response = client.GetAsync(uri_obj).get();
response.EnsureSuccessStatusCode();

auto stream = response.Content().ReadAsInputStreamAsync().get();

auto content_type = response.Content().Headers().ContentType().MediaType();

auto content_type_w = converter.from_bytes(content_type);
auto media_stream_type = winrt::Windows::Media::Core::MediaStreamType::FromMediaType(content_type_w);

auto media_stream_source = winrt::Windows::Media::Core::MediaStreamSource::CreateFromInputStream(stream);
media_stream_source.AddMediaStream(media_stream_type, stream);
media_source = winrt::Windows::Media::Core::MediaSource(media_stream_source);
}

void WindowsMediaPlayer::Play(const std::string& uri, const std::map<std::string, std::string>& headers) const {
winrt::Windows::Media::Core::MediaSource media_source;
CreateMediaSource(uri, headers, media_source);

winrt::Windows::Media::Playback::MediaPlayer player;
player.Source(media_source);
player.Play();
}
`

@jakky1
Copy link
Owner

jakky1 commented Mar 11, 2023

Hi,
I cannot find the symbols MFNETSOURCE_HTTP_REQUEST_HEADERS and MFCreateCredentialManager in your sample code above.
BTW, please don't use ChatGPT without validation.

@TSCSOftware
Copy link
Author

TSCSOftware commented Mar 11, 2023

@jakky1
Copy link
Owner

jakky1 commented Mar 11, 2023

Yes there is a class called IMFHttpDownloadRequest.
As this page mentioned,

Applications implement this interface to override the default implementation of the HTTP and HTTPS protocols used by Microsoft Media Foundation.

It means this package must to implement a http client to do it.
Not only the IMFHttpDownloadRequest, app should implemet IMFHttpDownloadSession and IMFHttpDownloadSessionProvider,
which is a hard work for me.
So I have no plan to do this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants