peilinok / screen-recorder

This repo has been archived, please visit https://github.com/peilinok/traa to get the new project!
GNU General Public License v3.0
152 stars 63 forks source link

speaker record with wasapi #4

Closed peilinok closed 4 years ago

peilinok commented 4 years ago

how to ensure that capture pcm data in a correct time line when speaker has no data(process silent data)

peilinok commented 4 years ago

First,this is cozed by push data into amix filter not correctly(size must be equal sample_rate * sample_size per second). According to Matthew van Eerde's blog,find a simple way to fix this,which is just render silent pcm data all the time,so the ready signal will be sent all time. Here is the blog: Playing silence via wasapi WASAPI loopback capture

There are a couple of oddities for WASAPI loopback capture. One is that “event mode” doesn’t work for loopback capture; you can call pAudioClient->Initialize(… AUDCLNT_STREAMFLAGS_LOOPBACK | AUDCLNT_STREAMFLAGS_EVENTCALLBACK, … ), you can call pAudioClient->SetEventHandle(…), and everything will succeed… but the “data is ready” event will never fire. So this app creates its own waitable timer.

Another oddity is that WASAPI will only push data down to the render endpoint when there are active streams. When nothing is playing, there is nothing to capture.

For example, play a song, and then run loopback-capture. While loopback-capture is running, stop the song, and then start it again. You’ll get this output when you start it back up:

>loopback-capture Press Enter to quit... IAudioCaptureClient::GetBuffer set flags to 0x00000001 on pass 5381 after 1088829 frames Thread HRESULT is 0x8000ffff

The flag in question is AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY. When the song stopped, no more data was available to capture. Eventually the song started up again, and WASAPI dutifully reported that there was a glitch detected. This app stops on glitches.

There are a couple of other possible ways to handle this. One way is to ignore glitches; then if you stop a song, wait a few seconds, and start it again, then the recorded signal will omit the wait and abut the two “audio is playing” portions.

But my particular favorite way of handling this is to run silence.exe. That way there are never any “nothing is playing” glitches, because there’s always something playing.