базовое воспроизведение с программно созданным Windows Media Player - PullRequest
2 голосов
/ 20 декабря 2009

Я пытался "просто быстро интегрировать" проигрыватель Windows Media через COM для воспроизведения отдельных файлов из локальной файловой системы или из источников http - но из-за скудной документации и сетевых ресурсов, используемых при не встраивая в какой-то контейнер Ole, я не смог бы заставить этот якобы тривиальный вариант использования работать.

Инициализация и т. Д. Работает нормально, но на самом деле воспроизведение какого-либо файла всегда дает сбой.

Пример кода, начиная с инициализации (обработка ошибок исключена, в основном переводится из примера C # на MSDN , выполняемого в основном потоке):

CComPtr<IWMPPlayer> player;
player.CoCreateInstance(__uuidof(WindowsMediaPlayer), 0, CLSCTX_INPROC_SERVER);
CComQIPtr<IWMPCore3> core(player);
CComPtr<IWMPControls> controls;
core->get_controls(&controls);
CComPtr<IWMPPlaylist> playlist;
core->get_currentPlaylist(&playlist);
CComBSTR path("c:\\bar.mp3"); // alternatively http://foo/bar.mp3

Первый подход к воспроизведению чего-либо дает «команда недоступна» :

core->put_url(path);
// ... waiting after that for WMP to load doesn't make a difference
controls->play(); // returns 0x000D1105 - NS_S_WMPCORE_COMMAND_NOT_AVAILABLE

Второй подход дает только S_OK с, но на самом деле ничего не воспроизводится:

CComPtr<IWMPMedia> media;
core->newMedia(path, &media);
playlist->appendItem(media);
controls->playItem(media); // returns S_OK, but doesn't play

Еще одна вещь, которую я заметил, это то, что core->get_playState() всегда возвращает wmposMediaOpening, независимо от того, как долго я жду.

Я наткнулся на один поток, который предполагает, что многопоточность может не работать должным образом с WMP, и этот код выполняется в многопоточной квартире. Может ли это быть проблемой?
Если нет, что еще может помешать WMP воспроизводить файлы?

Известный фон:
Экземпляр WMP создается в DLL с браузером в качестве хост-процесса.

Обновление:
Попытка простого DirectShow, который WMP должен использовать сам, демонстрирует более конкретную проблему - см. Вопрос для этого .

Ответы [ 2 ]

3 голосов
/ 23 декабря 2009

WMP поддерживает два метода автоматизации: встроенный ActiveX или COM-сервер. Для встроенного использования вы добавляете ActiveX через тег объекта (выполняете некоторые скрипты через IHTMLWindow2 из вашего BHO / Band) или скрытую форму и оттуда автоматизируете. См. Использование элемента управления проигрывателя Windows Media на веб-странице и Размещение элементов управления проигрывателя Windows Media в приложении Windows с примерами кодов.

Для использования COM-сервера, просто создайте плеер как COM-сервер и автоматизируйте его. Вы можете либо сделать его механизмом воспроизведения без пользовательского интерфейса , либо дистанционно, чтобы у вас был полный пользовательский интерфейс .

Проигрыватель Windows Media воспроизводится асинхронно, например, он может вызвать IMediaControl :: Run и сразу же вернуться при вызове put_URL (другой немедленный вызов play не будет выполнен, поскольку он уже воспроизводится). Если вам не нужно автоматическое воспроизведение, я думаю, вам нужен IWMPSettings :: put_autoStart.

WMP предполагает, что он находится в главном потоке. Если вы работаете в рабочем потоке или в потоке MTA, я предлагаю вам охватить другой процесс для его автоматизации или удаленного использования в качестве сервера вне процесса.

0 голосов
/ 27 декабря 2009

После дальнейшего исследования выяснилось, что это на самом деле было вызвано обходным решением VS2005 для VS2008s AtlSetPerUserRegistration(), которое всегда было активным - но должно было быть только для регистрации / отмены регистрации отдельных серверов COM. 1004 *

Обходной путь переопределяет HKEY_LOCAL_MACHINE с HKEY_CURRENT_USER, что, очевидно, приводит к сбою некоторых компонентов, если они создаются внутри процесса.

...