I'm trying to create a WPF application that allows me to select an audio source, which comes from a video, microphone, input audio, or other device connected to the PC and send it to an audio device that is connected to the PC.
To test, I used MediaElement but it only lets me select a video, I can't select another source, and I can't select the output device.
I tried to see NAudio and also Unosquare.FFME but I couldn't figure out how to solve the problem.
Thank you so much for your help
With NAudio you can do that easily.
You can get all available devices on computer by using the class MMDeviceEnumerator. Call the static function named EnumerateAudioEndPoints.
Example:
using NAudio.CoreAudioApi;
using (var devices = new MMDeviceEnumerator())
{
foreach (var device in devices.EnumerateAudioEndPoints(DataFlow.All, DeviceState.Active))
{
// do something with device
}
}
The DataFlow enum you can choise between input or output devices.
Related
I am trying to record two audio input (webcam + microphone) and one video input (webcam) via MediaCapture from C#. Just 1 audio and 1 video input works like a charm but the class itself does not allow to specify two audio input device ids.
An example:
var captureDeviceSettings = new MediaCaptureInitializationSettings
{
VideoDeviceId = videoDeviceId, #Webcam video input
AudioDeviceId = audioDeviceId, #Webcam audio input
StreamingCaptureMode = StreamingCaptureMode.AudioAndVideo,
}
I thought about using audio graph and using a submix node but, I need to specify a device ID for the media capture, the submix node does not give that. Further on, using the output device of audio graph seems not like the solution, I do not want to play microphone to default output device. Tried that but sounds horrible. I thought about creating a virtual audio device but I don't know how.
Any suggestions on that?
MediaCapture won't be able to do this, WASAPI maybe possibile, but it is not trivial to do.
Best option may be to utilize https://learn.microsoft.com/en-us/windows/win32/coreaudio/loopback-recording.
You will still have to mux in video stream though if you get loopback recording to work.
I am using a MediaPlaybackList to essentially 'stream' audio data coming in via Bluetooth as a byte[] on a fixed time gather interval. According to the MS documentation, MediaPlaybackList is 'gapless' playback between audio samples. But in my case, I have a popping sound and gap when transitioning to the next audio sample.
byte[] audioContent = new byte[audioLength];
chatReader.ReadBytes(audioContent);
MediaPlaybackItem mediaPlaybackItem = new MediaPlaybackItem(MediaSource.CreateFromStream(new MemoryStream(audioContent).AsRandomAccessStream(), "audio/mpeg"));
playbackList.Items.Add(mediaPlaybackItem);
if (_mediaPlayerElement.MediaPlayer.PlaybackSession.PlaybackState != MediaPlaybackState.Playing)
{
_mediaPlayerElement.MediaPlayer.Play(); ;
}
How can I achieve truly 'gapless' streaming audio using a method similar to this?
Also, I have tried writing my stream to a file realtime as the data comes in just to see if the popping sound or the gap is there. It plays from the file that the bytes are appended to perfectly with no pop or gap.
using (var stream = await playbackFile.OpenStreamForWriteAsync())
{
stream.Seek(0, SeekOrigin.End);
await stream.WriteAsync(audioContent, 0, audioContent.Length);
}
The MediaPlayer and in particular the MediaPlayerList is not designed to be used with a "live" audio stream. You must finish writing the data to the byte stream before adding it to the list and starting the MediaPlayer. Using the MediaPlayer is not the correct solution for this particular scenario.
A better solution would be to use the Audio Graph. The Audio Graph allows you to add input sources from actual audio endpoints so you don't need to fill the byte buffer with the streaming audio. You can then use sub-mix nodes to mix between the audio endpoint streams with no clicks or pops.
I'm trying to get image from a usb device using Aforge (directShow). The device (USB3HDCAP) has 3 diferent inputs (HDMI, DVI and S-Video). Using the code above, i can access and get the default input image (only from HDMI). However, when I change the physical input on the device (from HDMI to DIV, example) the image is black. What can i do to get video from other input (DVI or S-Video).
LocalWebCamsCollection = new FilterInfoCollection(FilterCategory.VideoInputDevice);
LocalWebCam = new VideoCaptureDevice(LocalWebCamsCollection[0].MonikerString);
LocalWebCam.NewFrame += new NewFrameEventHandler(Cam_NewFrame);
LocalWebCam.Start();
Your code snippet is what just captures video. To switch inputs on video capture hardware you need to use crossbar to re-configure the device.
In plain DirectShow it is like his:
Crossbar filter change current input to Composite
DirectShow USB webcam changing video source
With AForge.NET you should be looking up for a similar method, e.g. see:
Start Capturing From S-Video
... VideoCaptureDivece.AvailableCrossbarVideoInputs gives array of available video inputs. VideoCaptureDivece.CrossbarVideoInput accepts what? - yes video input. So combine those two together:
VideoKaynagi.CrossbarVideoInput = CrossbarVideoInput.AvailableCrossbarVideoInputs[0];
Of course you need to change 0 with an index of the S-Video input.
I'd like to be able to mix the microphone output with a mp3-File, and output that to a specific device.
I got playing the mp3-File to a specific device working:
Mp3FileReader reader = new Mp3FileReader("C:\\Users\\Victor\\Music\\Musik\\Attack.mp3");
var waveOut = new WaveOut();// or WaveOutEvent()
waveOut.DeviceNumber = deviceId; //deviceId, like 0 or 1
waveOut.Init(reader);
waveOut.Play();
So would I would like to be able to do is basically send the microphone output always to specific output and overlay that output to that specific device with the sound of a mp3-file when for example a button is pressed.
Now is what I'm trying to do possible with naudio and if so how would I go about it?
Thanks!
The basic strategy is to put the audio rececived from the microphone into a BufferedWaveProvider. Then turn that into an ISampleProvider with the ToSampleProvider extension method. Now you can pass that into a MixingSampleProvider. Then play from the MixingSampleProvider. Now at any time you can mix in other audio by adding an input into the MixingSampleProvider
I would like to see the current playout buffer value while streaming a video on a network over a wireless link,
I couldn't find any software that does this so i have decided to write a small app that can show me the current buffer size.
I have put a windows media player object in a form which plays a video from a URL that I specify, Is there any way to display the current buffer size s the video is played out?
Thanks
You can access the bufferingProgress property with this code:
int progressPercent = axWindowsMediaPlayer1.network.bufferingProgress;
IWMPNetwork interface
http://msdn.microsoft.com/en-us/library/windows/desktop/dd563492(v=vs.85).aspx