5

最近、私はすでにこの質問に似た解決策を求めました:

「待機」オプションを使用して mcisendstring で再生している mp3 ファイルを一時停止/停止する方法はありますか?

トラックが実行されている現在の秒に応じてスライダーが移動し、現在のトラックが再生された後に次のトラックに移動する機能を使用しながら、人々が継続的にサウンドを再生できるようにする機能をオーディオプレーヤーに実装したいと考えています。以上

(リンクで読むことができるように)それをやろうとした後

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));
    }
}

また、対応する mciSendString 関数も呼び出す Pause/Resume メソッドを使用して、ここでミューテックスをロック/ロック解除する別の機能を追加しました。

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

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

ここで一時停止を呼び出すと、mciSendString はトラックを一時停止し、カウンターをロックして、カウントダウンを続けないようにします。

ただし、問題は、まだ機能しないことです。mciSendString で待機オプションを使用せずに解決策を考えようと努力したにもかかわらず、一時停止は音楽の再生にまったく影響しません。

何かアドバイス?

編集:これは実際にスレッドが原因で発生していることがわかりました。私はかなりの時間 C# を使用してきましたが、Invokes を使用してスレッドの問題を回避できます。もしかしたら、ここでも可能ですか?

EDIT2:少し読んだところ、PostMessage WinAPI呼び出しを介して別のスレッドのメッセージキューにメソッドを投稿するオプションがあるようです。これは可能性がありますか?はいの場合、誰かが良い例を提供できますか? 少し読んだけど、いまいちよくわからない

C++にもこのようなものはありますか?

4

1 に答える 1

5

編集:これは実際にスレッドが原因で発生していることがわかりました。私はかなりの時間 C# を使用しており、Invokes を使用してスレッドの問題を回避できます。

はい。非同期イベントにユーザーランド スレッドが必要な場合はキューに入れられたメッセージが一連のアクションになります (C# (または Java など) の UI スレッドの呼び出しなど)。それは大変な作業です。

EDIT2:少し読んだところ、PostMessage WinAPI呼び出しを介して別のスレッドのメッセージキューにメソッドを投稿するオプションがあるようです。これは可能性がありますか?はいの場合、誰かが良い例を提供できますか? ちょっと読んだけどよくわからない

C++にもこのようなものはありますか?

あなたが言及しているのは、ほぼ¹すべてのUIフレームワークの根底にある一般的なメッセージポンプ/イベントループです。C++ には GUI がネイティブに「ありません」が、同様の機能を持つライブラリが存在することは確かです。

Boost Asioは特筆すべきものでした。既に GUI フレームワークをお持ちの場合は、独自のイベント ループ (Qt、MFC など) があります。

使用されているものに関係なく、すべての Win32 GUI アプリケーションは、実際にメッセージの投稿を許可する、参照したメッセージ ポンプを使用することになります。 GUI フレームワークを積極的に開発している場合を除き、これはほとんどの場合、間違ったレベルの抽象化です²

いつでも独自のビルドを作成できます。メッセージを受信するためのある種の(優先)キューを用意し、これらを処理するメインループを用意するだけです。それらをイベントと呼んでください。イベント駆動型の設計です。


¹ 現時点では、https://github.com/ocornut/imguiのような新しい基本に立ち返る波があります。

²この質問が存在するという事実は、あなたがそれをしていないことを示しています

于 2016-01-19T12:52:01.037 に答える