2016-01-13 3 views
4

Недавно я уже просил решение, похожее на это вопросы:mciSendString не пауза звук воспроизводится с резьбой

Is there a way to pause/stop a mp3 file playing with mcisendstring with the "wait" option?

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

После (как вы можете прочитать в ссылке), пытающегося сделать это с помощью

mciSendString("play mp3 wait", NULL, 0, NULL); 

который не удалось из-за проблемы, что трек не может быть приостановлен или остановлен до его завершения, теперь я пытаюсь реализовать его по-другому. В настоящее время, когда я начинаю играть на треке, я также запускаю еще один поток, который запускает счетчик. Счетчик получает длину трека в секундах и отсчитывает время, также предлагая мьютекс для приостановки/возобновления счетчика. Чтобы остановить мой MusicCycle от простого цикла без контроля, я присоединяюсь к потоку, поэтому жду его завершения.

void Music::MusicCycle(std::wstring trackPath) 
{ 
    while (true) 
    { 
     OpenMP3(trackPath); 
     mciSendString("play mp3", NULL, 0, NULL); 

     m_counterThread = boost::thread(boost::bind(&Counter::StartCount, m_counter, <length of track in seconds>)); 
     m_counterThread.join(); 

     //... Get new track here 
    } 
} 

Обратите внимание, что весь этот метод создается в потоке, а также:

m_cycleThread = boost::thread(boost::bind(&Music::MusicCycle, this, trackPath)); 

Нить запускается функция MusicCycle выглядит так:

void Counter::StartCount(int seconds) 
{ 
    boost::mutex::scoped_lock lock(m_mutex); 

    for (int i = 0; i < seconds; i++) 
    { 
     while (m_counterLock) 
     { 
      m_condVar.wait(lock); 
     } 

     boost::this_thread::sleep(boost::posix_time::seconds(1)); 
    } 
} 

Кроме того, я добавил еще одна функция блокировки/разблокировки мьютекса здесь с помощью моих методов Pause/Resume, которые также вызывают соответствующие функции mciSendString

mciSendString("resume mp3", NULL, 0, NULL); 

mciSendString("pause mp3", NULL, 0, NULL); 

Когда я позвоню в паузу, mciSendString остановит дорожку, а также заблокирует счетчик, чтобы он не продолжал отсчет.

Однако проблема в том, что она по-прежнему не работает. Пауза просто не влияет на воспроизведение музыки, несмотря на мои попытки придумать решение без использования опции wait в mciSendString

Любые советы?

EDIT: Оказывается, это происходит из-за резьбы. Я занимаюсь C# в течение достаточного количества времени, и вы можете использовать Invokes для решения проблем с потоком. Может быть, это возможно и здесь?

EDIT2: Я немного прочитал и кажется, что есть возможность отправить метод в очереди сообщений другого потока через вызов PostMessage WinAPI. Возможно ли это здесь? Если да, может ли кто-нибудь представить хороший пример? Я немного почитал, но я до сих пор не очень разбираюсь

Есть ли что-то подобное на C++?

+1

Вы можете упростить ? Работает ли команда MCI в более простом приложении? Почему вы все время создаете новый поток? Рассматривали ли вы использование Boost Asio и правильные часы для измерения времени (возможно, у MCI есть транспортный интерфейс, который может указать вам фактическую позицию в треке, так что вам не нужно делать все героики). – sehe

+0

@sehe Один поток сделан так, что пользовательский интерфейс не будет висеть, когда я продолжаю играть, а другой для счетчика, чтобы он не мешал игре играть. И да, это работает, если я не пытаюсь сделать это через потоки. Мне, возможно, придется заглянуть в asio, но счетчик на самом деле не мешает мне сейчас, это скорее проблема кросс-нити mcisendstring. – Sossenbinder

+0

Вам не понадобится счетчик без нарезания резьбы. Кроме того, я спросил: «Почему вы порождаете новый поток *** все время ***». Вы ответили только на первую (очевидную) часть – sehe

ответ

5

EDIT: Оказывается, это происходит из-за резьбы. Я занимаюсь C# в течение достаточного количества времени, и вы можете использовать Invokes для решения проблем с потоком.

Да. Ifff вам нужен поток пользовательской земли для асинхронных событий , а затем сообщение в очереди - ваш курс действий (например, C# (или Java и т. Д.).) invoke-on-UI-thread). Это тяжелая работа.

EDIT2: Я немного прочитал и кажется, что есть возможность отправить метод в очереди сообщений другого потока через вызов PostMessage WinAPI. Возможно ли это здесь? Если да, может ли кто-нибудь представить хороший пример? Я немного почитал, но я до сих пор не очень разбираюсь

Есть ли что-то подобное на C++?

Что вы имеете в виду, это всего лишь общий цикл сообщений-насосов/событий, который лежит в основе почти всех интерфейсов UI. C++ не имеет «иметь» GUI изначально, но, конечно, существуют библиотеки, которые имеют аналогичные возможности.

Boost Asio был одним упоминаемым. Если у вас уже есть инфраструктура GUI, у нее будет собственный цикл событий (Qt, MFC и т. Д.).

Независимо от того, что используется, все приложения Win32 GUI заканчиваются использованием сообщения, на которое вы ссылались, что действительно позволяет отправлять сообщения. Это почти всегда неправильный уровень абстракции, если вы не активно разрабатываете свою графическую оболочку².

Вы всегда можете создать свой собственный. Просто иметь некоторую (приоритетную) очередь для получения сообщений и иметь основной цикл, обрабатывающий их. Назовите их событиями и pronto: дизайн, управляемый событиями.


¹ есть волна назад в тот момент, с новомодными назад к основам, как https://github.com/ocornut/imgui

² тот факт, что существует этот вопрос подсказывает мне, что вы не делаете, что

Смежные вопросы