Need example for recording STEREO-MIX + MIC

Started by G.,

G.

Hi everyone...
I need to record Stereo Mix and Mic in an unique output file (AAC if possible..)
I think that i must use WASAPI...
where I can get example of recording via WASAPI..
and mixing channels

it's better record two separate file and mix at the end? or directly mix them during recording?

sorry for my english
Thanks in advance

PS I use Bass.Net

radio42

A recording sample is provided in the Sample subdirectory of the full Bass.Net installation.

Or take a look to the BaseEncoder class in the documentation which provides an abstract framework for encoding.
https://www.radio42.com/bass/help/html/53d3394f-6acf-c797-c21e-700ce5204826.htm

Ian @ un4seen

Quote from: G.I need to record Stereo Mix and Mic in an unique output file (AAC if possible..)

Are the "Stereo Mix" and "Mic" inputs on different devices/soundcards? Note that most soundcards will only allow one active input at a time. But you can avoid that issue by using the output's "loopback" device instead of "Stereo Mix".

Quote from: G.I think that i must use WASAPI...
where I can get example of recording via WASAPI..
and mixing channels

BASS uses WASAPI by default, so you don't need to do anything special to enable that. You can use the BASSmix add-on to mix the recordings, and the BASSenc add-on for file writing: create a mixer, plug the 2 recordings into it, and set an encoder on the mixer. It could look something like this:

BASS_RecordInit(recdev1); // initialize 1st recording device
BASS_RecordInit(recdev2); // initialize 2nd recording device

mixer = BASS_Mixer_StreamCreate(freq, chans, BASS_STREAM_DECODE); // create the mixer
encoder = BASS_Encode_MP3_StartFile(mixer, NULL, BASS_ENCODE_AUTOFREE, "mix.mp3); // set an encoder on it

BASS_RecordSetDevice(recdev1); // set device for 1st recording
rec1 = BASS_RecordStart(freq, chans, 0, RECORDPROC_NONE, 0); // start 1st recording
BASS_Mixer_StreamAddChannel(mixer, rec1, BASS_STREAM_AUTOFREE); // add it to the mix

BASS_RecordSetDevice(recdev2); // set device for 2nd recording
rec2 = BASS_RecordStart(freq, chans, 0, RECORDPROC_NONE, 0); // start 2nd recording
BASS_Mixer_StreamAddChannel(mixer, rec2, BASS_STREAM_AUTOFREE); // add it to the mix

// processing loop
while (!stop) {
BYTE bufer[50000]; // processing buffer
int avail1 = BASS_ChannelGetData(rec1, 0, BASS_DATA_AVAILABLE); // got amount available from 1st recording
int avail2 = BASS_ChannelGetData(rec2, 0, BASS_DATA_AVAILABLE); // got amount available from 2nd recording
int got = BASS_ChannelGetData(mixer, buffer, min(min(avail1, avail2), sizeof(buffer))); // process the amount available from both
Sleep(50); // wait a bit for more data
}

BASS_ChannelFree(mixer); // free the mixer (and recordings and encoder due to AUTOFREE)

Please see the documentation for details on the mentioned functions.


G.

Great... I made a little test application and it works very well... thanks...

Only a question: there is a possibility that recording channel haven't audio, in this case mixer stop parsing data, right?

file created from encoder couldn't have same duration of "recording time"?
I see flag BASS_MIXER_NONSTOP for mixer... but if I push data... how this could working?

always... sorry for my worst english.... :)
thanks again

G.

    Private Sub StartRecording()

        ffmpegProcess = New Process()
        ffmpegProcess.StartInfo.CreateNoWindow = True
        ffmpegProcess.StartInfo.UseShellExecute = False
        ffmpegProcess.StartInfo.RedirectStandardOutput = True
        ffmpegProcess.StartInfo.FileName = IO.Path.Combine(Application.StartupPath, "ffmpeg.exe")

        Dim ffmpegArguments = "-fflags +genpts+igndts -f gdigrab -framerate 30 -video_size {2}x{3} -offset_x {0} -offset_y {1} -i desktop -vf "
        ffmpegArguments &= """drawtext=fontfile='C\:/Windows/Fonts/arial.ttf':text='%{{localtime\:%Y-%m-%d}} %{{localtime\:%X}}':x=10:y=10:fontsize=20:fontcolor=white:"
        ffmpegArguments &= "box=1:boxcolor=black@0.8:boxborderw=5"" -an -c:v libx264 -preset ultrafast -crf 16 -pix_fmt yuv420p -r 30 ""{4}"" -y"

        Dim filename As String = IO.Path.Combine(RecordingFolder, Now.ToString("yyyy.MM.dd_hhmmss"))

        If Screen.AllScreens.Count = 1 Then
            With Screen.PrimaryScreen
                ffmpegArguments = String.Format(ffmpegArguments, .Bounds.X, .Bounds.Y, .Bounds.Width, .Bounds.Height, filename & "_video.mkv")
            End With
        Else
            With Screen.AllScreens.Where(Function(T) T.Primary = False).Last
                ffmpegArguments = String.Format(ffmpegArguments, .Bounds.X, .Bounds.Y, .Bounds.Width, .Bounds.Height, filename & "_video.mkv")
            End With
        End If

        ffmpegProcess.StartInfo.Arguments = ffmpegArguments

        Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)

        Dim micDevice As Integer
        For d As Integer = 0 To Bass.BASS_RecordGetDeviceInfos.Count - 1
            With Bass.BASS_RecordGetDeviceInfos(d)
                If .id IsNot Nothing AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_ENABLED) AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_DEFAULTCOM) Then
                    micDevice = d : Exit For
                End If
            End With
        Next d

        Dim loopbackDevice As Integer
        For d As Integer = 0 To Bass.BASS_RecordGetDeviceInfos.Count - 1
            With Bass.BASS_RecordGetDeviceInfos(d)
                If .id IsNot Nothing AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_ENABLED) AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_LOOPBACK) Then
                    If .id <> Bass.BASS_RecordGetDeviceInfos(micDevice).id Then
                        loopbackDevice = d : Exit For
                    End If
                End If
            End With
        Next d

        Bass.BASS_RecordInit(loopbackDevice) : Bass.BASS_RecordInit(micDevice)
        Dim mixer As Integer = AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_MIXER_NONSTOP Or BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
        Dim encoder As Integer = AddOn.EncAac.BassEnc_Aac.BASS_Encode_AAC_StartFile(mixer, "--bitrate 160000", AddOn.Enc.BASSEncode.BASS_ENCODE_AUTOFREE, filename & "_audio.aac")

        Bass.BASS_RecordSetDevice(loopbackDevice)
        Dim recHandle1 As Integer = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, BASSRecordProc.RECORDPROC_NONE, IntPtr.Zero)
        AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixer, recHandle1, BASSFlag.BASS_STREAM_AUTOFREE)

        Bass.BASS_RecordSetDevice(micDevice)
        Dim recHandle2 As Integer = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, BASSRecordProc.RECORDPROC_NONE, IntPtr.Zero)
        AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixer, recHandle2, BASSFlag.BASS_STREAM_AUTOFREE)

        stopRecording = False
        ffmpegProcess.Start()
        Bass.BASS_ChannelPlay(recHandle1, False)
        Bass.BASS_ChannelPlay(recHandle2, False)

        Do Until stopRecording
            Dim buffer(50000) As Byte
            Dim avail1 As Integer = Bass.BASS_ChannelGetData(recHandle1, 0, BASSData.BASS_DATA_AVAILABLE)
            Dim avail2 As Integer = Bass.BASS_ChannelGetData(recHandle2, 0, BASSData.BASS_DATA_AVAILABLE)
            Dim x As Integer = Bass.BASS_ChannelGetData(mixer, buffer, Math.Min(Math.Min(avail1, avail2), buffer.Length))
            Threading.Thread.Sleep(100)
        Loop

        ffmpegProcess.Kill()
        Bass.BASS_ChannelStop(recHandle1)
        Bass.BASS_ChannelStop(recHandle2)
        Bass.BASS_ChannelFree(mixer)

        ffmpegProcess = New Process()
        ffmpegProcess.StartInfo.CreateNoWindow = True
        ffmpegProcess.StartInfo.UseShellExecute = False
        ffmpegProcess.StartInfo.RedirectStandardOutput = True
        ffmpegProcess.StartInfo.FileName = IO.Path.Combine(Application.StartupPath, "ffmpeg.exe")
        ffmpegArguments = String.Format("-i ""{0}"" -i ""{1}"" -c:v copy -c:a aac -map 0:v:0 -map 1:a:0 -shortest ""{2}"" -y", filename & "_video.mkv", filename & "_audio.aac", filename & ".mkv")
        ffmpegProcess.StartInfo.Arguments = ffmpegArguments
        ffmpegProcess.Start()
        ffmpegProcess.WaitForExit()

Okay, this is my function for capturing audio and the desktop of the second monitor...

I capture the desktop with ffmpeg and the audio with bass...
The problem is that (it seems, I need to verify this with accurate tests) the audio file that is then muxed with the video file does not contain silence... except for the final silence... so if I don't have audio at the beginning, the audio file will be shorter than the video file... and as a result, I will lose synchronization.... How can I solve this?

Translated with DeepL.com (free version)

Ian @ un4seen

Quote from: G.Only a question: there is a possibility that recording channel haven't audio, in this case mixer stop parsing data, right?

I guess it's the "loopback" recording that you're seeing stop? A "loopback" recording will stall when the corresponding output device is inactive. If you would like to continue mixing when that happens, you can modify the code to ignore its available data (BASS_DATA_AVAILABLE):

...
    int avail = BASS_ChannelGetData(rec2, 0, BASS_DATA_AVAILABLE); // got amount available from 2nd recording (Mic)
    int got = BASS_ChannelGetData(mixer, buffer, min(avail, sizeof(buffer))); // process the amount available
...

Another option is to set the BASS_MIXER_CHAN_LIMIT flag on the Mic recording:

...
BASS_Mixer_StreamAddChannel(mixer, rec2, BASS_STREAM_AUTOFREE | BASS_MIXER_CHAN_LIMIT); // add it to the mix and limit the mix to its available amount
...
    int got = BASS_ChannelGetData(mixer, buffer, sizeof(buffer)); // process

Please see the BASS_Mixer_StreamAddChannel documentation for details.

G.

Thanks Ian... it works well...

But I was wondering... shouldn't we use a silent channel as a guide for the other two? That way we can be sure that whatever happens, the audio will always be the same length as the video.

Ian @ un4seen

When there's a live source in a mix, it's usually best to have it provide the clock, ie. it controls the mixer's processing rate. Because if the mixer's clock is running at a slightly different rate (a clock doesn't always exactly match its nominal rate), then the live source may have either cracks in the mix if it's running slower or creeping latency if it's running faster.

G.

Hi Ian... OK, I'll leave the microphone channel as the driver...

However, I've noticed that no audio is coming out of the loopback device...

Bass.BASS_ChannelGetData(rechandle1, 0, BASSData.BASS_DATA_AVAILABLE)

always returns 0...

At first, I thought I was wrong in choosing the exact loopback device... but now I'm convinced that... the application from which I need to capture the audio uses WASAPI and therefore appears in the Windows mixer list with its application name...

Do I need to use BASS_WASAPI to retrieve the audio played by the application?

Translated with DeepL.com (free version)

Ian @ un4seen

"loopback" recording is a WASAPI feature, so BASS has to (and does) use WASAPI for that. All other recording (eg. the Mic) uses WASAPI too by default (see the BASS_CONFIG_REC_WASAPI option).

When are you making that BASS_ChannelGetData(BASS_DATA_AVAILABLE) call? It would need to be just before the mixer's BASS_ChannelGetData call because the mixer takes data from the recording, so the recording may well have 0 data available after that. You could use BASS_ChannelGetPosition instead to monitor the loopback recording, ie. is that stuck on 0?

If the problem persists, you could try running the pre-compiled RECTEST.EXE example included in the BASS package (C\BIN folder) and see if that captures anything from the loopback device. If it does, then perhaps your app is recording from the wrong device? Do you have multiple loopback devices? Note there's one for each output device.

G.

Okay... I was wrong to take only one loopback channel on my PC, which actually has multiple sound cards installed...

Now I select the microphone channel and all enabled loopback channels in the mixer (in my case, I checked and there are three... the first two don't give any audio... the third one does)....

This is the code as I modified it... now everything works perfectly...


        Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)

        Dim mixer As Integer = AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_MIXER_NONSTOP Or BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
        Dim encoder As Integer = AddOn.EncAac.BassEnc_Aac.BASS_Encode_AAC_StartFile(mixer, "--bitrate 160000", AddOn.Enc.BASSEncode.BASS_ENCODE_AUTOFREE, filename & "_audio.aac")

        Dim micHandle As Integer
        For d As Integer = 0 To Bass.BASS_RecordGetDeviceInfos.Count - 1
            With Bass.BASS_RecordGetDeviceInfos(d)
                If .id IsNot Nothing AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_ENABLED) AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_DEFAULTCOM) Then
                    Bass.BASS_RecordInit(d) : Bass.BASS_RecordSetDevice(d)
                    micHandle = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, BASSRecordProc.RECORDPROC_NONE, IntPtr.Zero)
                    AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixer, micHandle, BASSFlag.BASS_STREAM_AUTOFREE)
                    Exit For
                End If
            End With
        Next d

        Dim listOfLoopbackDevice As New List(Of Integer)
        For d As Integer = 0 To Bass.BASS_RecordGetDeviceInfos.Count - 1
            With Bass.BASS_RecordGetDeviceInfos(d)
                If .id IsNot Nothing AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_ENABLED) AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_LOOPBACK) Then
                    Bass.BASS_RecordInit(d) : Bass.BASS_RecordSetDevice(d)
                    listOfLoopbackDevice.Add(Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, BASSRecordProc.RECORDPROC_NONE, IntPtr.Zero))
                    AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixer, listOfLoopbackDevice.Last, BASSFlag.BASS_STREAM_AUTOFREE)
                End If
            End With
        Next d

        stopRecording = False
        ffmpegProcess.Start()
        Bass.BASS_ChannelPlay(micHandle, False)
        listOfLoopbackDevice.ForEach(Sub(T) Bass.BASS_ChannelPlay(T, False))

        Do Until stopRecording
            Dim buffer(50000) As Byte
            Dim textline As String = ""
            listOfLoopbackDevice.ForEach(Sub(T) textline &= " - " & Bass.BASS_ChannelGetData(T, 0, BASSData.BASS_DATA_AVAILABLE))
            Console.WriteLine(textline)
            Dim avail2 As Integer = Bass.BASS_ChannelGetData(micHandle, 0, BASSData.BASS_DATA_AVAILABLE)
            Dim x As Integer = Bass.BASS_ChannelGetData(mixer, buffer, Math.Min(avail2, buffer.Length))
            Threading.Thread.Sleep(100)
        Loop

        ffmpegProcess.Kill()
        Bass.BASS_ChannelStop(micHandle)
        listOfLoopbackDevice.ForEach(Sub(T) Bass.BASS_ChannelStop(T))
        Bass.BASS_ChannelFree(mixer)



Thanks Ian for the time you dedicated to me.


Translated with DeepL.com (free version)

G.

Hi everyone...

The procedure described above works pretty well...
Right now, I'm recording a video stream and an audio stream (a track mixed using loopback devices and a microphone), and at the end of the recording, I merge the files into a single MKV file...

I was wondering... is it possible to use the FFmpeg process that records the video while passing the mixer track stream as the audio input? So that the combined file is created in real time?

Has anyone ever done this? / Can you tell me how to do it?

Thanks

Translated with DeepL.com (free version)

G.

sorry... i can't edit post and so i need to write another...

Here's another question I wanted to ask:

When I write an AAC file, ffprobe gives me an approximate file duration...

So I have to convert it to M4A first (still using FFmpeg) and then run ffprobe again... and then it gives me the exact duration...

Is it possible to record directly in M4A?
Or what would be best for me? OGG? MP3?

All this confusion is because I'm trying to maintain/calculate the time sync between video and audio...


Translated with DeepL.com (free version)

Ian @ un4seen

Quote from: G.The procedure described above works pretty well...
Right now, I'm recording a video stream and an audio stream (a track mixed using loopback devices and a microphone), and at the end of the recording, I merge the files into a single MKV file...

I was wondering... is it possible to use the FFmpeg process that records the video while passing the mixer track stream as the audio input? So that the combined file is created in real time?

Has anyone ever done this? / Can you tell me how to do it?

I'm not very familiar with ffmpeg, but I guess that may be possible with BASS_Encode_Start. To use ffmpeg for AAC-in-MKV encoding, I think you would do something like this:

encoder = BASS_Encode_Start(mixer, "ffmpeg -i - -c:a aac output.mkv", BASS_ENCODE_AUTOFREE, 0, 0);

You can try adding your video options to that.

G.

Hi Ian, I've been out of town for a few days... I'll try it out soon and let you know...

Thanks

G.

Quote from: G.Hi Ian, I've been out of town for a few days... I'll try it out soon and let you know...

Thanks

Nothing, I can't get it to work like that...

Instead... is there a way to shift the loopback device track back by 0.5 seconds? I need it to sync both audio tracks

Ian @ un4seen

Quote from: G.Nothing, I can't get it to work like that...

I tried the command just now and it did work, ie. it created an MKV file with an AAC track. Is it not working at all for you, or only when you add other options to the command? Is the BASS_Encode_Start call failing (returning 0), and if so, what is the error code?

Quote from: G.is there a way to shift the loopback device track back by 0.5 seconds? I need it to sync both audio tracks

You can delay a source in a mix with BASS_Mixer_StreamAddChannelEx's "start" parameter. For example:

BASS_Mixer_StreamAddChannelEx(mixer, source, 0, BASS_ChannelSeconds2Bytes(mixer, delay_secs), 0);

G.

QuoteI tried the command just now and it did work, ie. it created an MKV file with an AAC track. Is it not working at all for you, or only when you add other options to the command? Is the BASS_Encode_Start call failing (returning 0), and if so, what is the error code?

Do you end up with an MKV file that contains only audio, or both video and audio?

I've tried these arguments:

Dim ffmpegArguments As String = "-fflags +genpts+igndts -f gdigrab -framerate 25 -video_size {2}x{3} -offset_x {0} -offset_y {1} -i desktop -vf " &
                                 """drawtext=fontfile='C\:/Windows/Fonts/arial.ttf':text='%{{localtime\:%Y-%m-%d}} %{{localtime\:%X}}':x=10:y=10:fontsize=20:" &
                                 "fontcolor=white:box=1:boxcolor=black@0.8:boxborderw=5"" -an -c:v libx264 -preset ultrafast -crf 22 -pix_fmt yuv420p -r 25 ""{4}"" -y"

But no matter where I put "-i - ", I can't create the file...
even though the handle doesn't return 0 but an integer

Translated with DeepL.com (free version)

Ian @ un4seen

I only tried the command-line that I posted above, so I got an MKV file with only audio. I'm not at all familiar with ffmpeg's video options, so I'm afraid I'm unable to help with those.

G.

       Dim ffmpegArguments As String = "-fflags +genpts+igndts -f gdigrab -framerate 25 -video_size {2}x{3} -offset_x {0} -offset_y {1} -i desktop -f s16le -ar 44100 -ac 2 -i - " &
                                       "-vf ""drawtext=fontfile='C\:/Windows/Fonts/arial.ttf':text='%{{localtime\:%Y-%m-%d}} %{{localtime\:%X}}':x=10:y=10:fontsize=20:" &
                                       "fontcolor=white:box=1:boxcolor=black@0.8:boxborderw=5"" -map 0:v -map 1:a -c:v libx264 -preset ultrafast -crf 22 -pix_fmt yuv420p -r 25 " &
                                       "-c:a aac ""c:\prova2\fftest.mkv"" -y"

       ffmpegArguments = String.Format(ffmpegArguments, Screen.PrimaryScreen.WorkingArea.X, Screen.PrimaryScreen.WorkingArea.Y, Screen.PrimaryScreen.WorkingArea.Width, Screen.PrimaryScreen.WorkingArea.Height)

       Bass.BASS_Init(0, 44100, BASSInit.BASS_DEVICE_DEFAULT, IntPtr.Zero)

       Dim mixer As Integer = AddOn.Mix.BassMix.BASS_Mixer_StreamCreate(44100, 2, BASSFlag.BASS_MIXER_NONSTOP Or BASSFlag.BASS_STREAM_DECODE Or BASSFlag.BASS_SAMPLE_FLOAT)
       Dim encoder = BassEnc.BASS_Encode_Start(mixer, "C:\Program Files\ffmpeg\bin\ffmpeg " & ffmpegArguments, BASSEncode.BASS_ENCODE_AUTOFREE, Nothing, 0)

       Dim micHandle As Integer
       For d As Integer = 0 To Bass.BASS_RecordGetDeviceInfos.Count - 1
           With Bass.BASS_RecordGetDeviceInfos(d)
               If .id IsNot Nothing AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_ENABLED) AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_DEFAULTCOM) Then
                   Bass.BASS_RecordInit(d) : Bass.BASS_RecordSetDevice(d)
                   micHandle = Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, BASSRecordProc.RECORDPROC_NONE, IntPtr.Zero)
                   AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixer, micHandle, BASSFlag.BASS_STREAM_AUTOFREE)
                   Exit For
               End If
           End With
       Next d

       Dim listOfLoopbackDevice As New List(Of Integer)
       For d As Integer = 0 To Bass.BASS_RecordGetDeviceInfos.Count - 1
           With Bass.BASS_RecordGetDeviceInfos(d)
               If .id IsNot Nothing AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_ENABLED) AndAlso .status.HasFlag(BASSDeviceInfo.BASS_DEVICE_LOOPBACK) Then
                   Bass.BASS_RecordInit(d) : Bass.BASS_RecordSetDevice(d)
                   listOfLoopbackDevice.Add(Bass.BASS_RecordStart(44100, 2, BASSFlag.BASS_RECORD_PAUSE, BASSRecordProc.RECORDPROC_NONE, IntPtr.Zero))
                   AddOn.Mix.BassMix.BASS_Mixer_StreamAddChannel(mixer, listOfLoopbackDevice.Last, BASSFlag.BASS_STREAM_AUTOFREE)
               End If
           End With
       Next d

       stopMe = False
       Bass.BASS_ChannelPlay(micHandle, False)
       listOfLoopbackDevice.ForEach(Sub(T) Bass.BASS_ChannelPlay(T, False))

       Do Until stopMe
           Dim buffer(50000) As Byte
           Dim avail As Integer = Bass.BASS_ChannelGetData(micHandle, 0, BASSData.BASS_DATA_AVAILABLE)
           Dim x As Integer = Bass.BASS_ChannelGetData(mixer, buffer, Math.Min(avail, buffer.Length))
           Application.DoEvents()
           Threading.Thread.Sleep(100)
       Loop

       Bass.BASS_ChannelStop(micHandle)
       listOfLoopbackDevice.ForEach(Sub(T) Bass.BASS_ChannelStop(T))
       Bass.BASS_ChannelFree(mixer)
       MessageBox.Show("Finish!!")

OK... updates....

I managed to get the combined video and audio recording to work... the code above is the current one...
The only thing is that instead of hearing the actual audio, I only hear a very loud noise/hiss... I think it has something to do with the encoding itself...


Ian @ un4seen

It looks like you're telling ffmpeg to expect raw (headerless) data with "-f s16le -ar 44100 -ac 2" in the command-line. Instead of doing that, it's usually better to have BASS_Encode_Start pass the sample format to the encoder via a WAVE header, which is what it does by default. But if you would prefer to use raw data then you can add the BASS_ENCODE_NOHEAD flag to the BASS_Encode_Start call. Please see the BASS_Encode_Start documentation for details.