Недавно я уже просил решение, похожее на это вопросы: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++?
Вы можете упростить ? Работает ли команда MCI в более простом приложении? Почему вы все время создаете новый поток? Рассматривали ли вы использование Boost Asio и правильные часы для измерения времени (возможно, у MCI есть транспортный интерфейс, который может указать вам фактическую позицию в треке, так что вам не нужно делать все героики). – sehe
@sehe Один поток сделан так, что пользовательский интерфейс не будет висеть, когда я продолжаю играть, а другой для счетчика, чтобы он не мешал игре играть. И да, это работает, если я не пытаюсь сделать это через потоки. Мне, возможно, придется заглянуть в asio, но счетчик на самом деле не мешает мне сейчас, это скорее проблема кросс-нити mcisendstring. – Sossenbinder
Вам не понадобится счетчик без нарезания резьбы. Кроме того, я спросил: «Почему вы порождаете новый поток *** все время ***». Вы ответили только на первую (очевидную) часть – sehe