Change Audio Stream in VideoLan DotNet for WPF - c#

We're using VideoLan DotNet for WPF to play DVD movies in our WPF application. Some movies have multiple audio stream. (for example in multiple languages) How can we choose the desired audio stream?
While searching VideoLan's Wiki, I found this:
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public int AudioTrack
{
get
{
return this.nativeVlc.GetVlcObjectInt(ObjectType.VLC_OBJECT_INPUT, "audio-es", -1);
}
set
{
this.nativeVlc.SetVlcObjectInt(ObjectType.VLC_OBJECT_INPUT, "audio-es", value);
}
}
But I can't find the same property in the project I'm using (Vlc.DotNet)
So how can I detect how many audio streams exist and choose one?

I found out how to do so (mediaPlayer is an instance of VlcControl):
We can count audio streams using mediaPlayer.AudioProperties.TrackCount and select the index using mediaPlayer.AudioProperties.Track.
Now is there any way to get their description? (They usually have a name such as "English")

i'm using VLC control in Windows form and my code for work
private void karaokeToolStripMenuItem_Click(object sender, EventArgs e)
{
// MessageBox.Show(axVLCPlugin21.audio.count.ToString(), "audio track");
if (axVLCPlugin21.audio.track == 1)
{
try
{
axVLCPlugin21.audio.track = 2;
}
catch (Exception ex)
{
// show Exception here by messageBox or other
//if there are exceptions, the file has only one track
}
}
else
axVLCPlugin21.audio.track = 1;
}
I hope to help you.

Related

Control the intensity of the flash light in xamain.forms

i am new to xamarin forms. now 'm developing a sample application for making a Torch. i got a nuget for On/Off the flash light. https://github.com/kphillpotts/Xamarin.Plugins/tree/master/Lamp . but i like to control the intensity of the flash light. i tried to use the native code but failed to do it. i search the google but cant find it .is there any way i can make it for achieving it.
Thank you in advance
I don't know a plugin that implements it. But you can easily extend the lamp plugin.
You could extend the interface ILamp like
public interface ILamp
{
///....
void TurnOn(float intensity);
}
then implement it by copying the TurnOn functionality
iOS
public void TurnOn(float intensity)
{
var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video);
if (captureDevice == null)
{
Debug.WriteLine("No captureDevice - this won't work on the simulator, try a physical device");
return;
}
NSError error = null;
captureDevice.LockForConfiguration(out error);
if (error != null)
{
Debug.WriteLine(error);
captureDevice.UnlockForConfiguration();
return;
}
else
{
if (captureDevice.TorchMode != AVCaptureTorchMode.On)
{
captureDevice.TorchMode = AVCaptureTorchMode.On;
NSError err;
captureDevice.SetTorchModeLevel(intensity, out err); // add this line
}
captureDevice.UnlockForConfiguration();
}
}
On Android I'm not sure if there is a API to control it. I can't find one. If there is one, just proceed like on iOS.
If the platform has no API, just implement TurnOn(float intensity) like
public void TurnOn(float intensity)
{
TurnOn();
}

How to implement Media player Listener In C# Xamarin Android?

I am developing one of my android app in xamarin platform in which i want to play audio using url and now i am able to play that file using url. So now i want perform following tasks where got stuck.
1) play file with seek bar according to file buffer size .
2) Unable to implement media player listener like OnComplitionListener specially in Xamarin.
Here i want share code that only playing audio without seekbar and media player listeners.
public void OnlinePlayer(String filePath)
{
try {
player.Reset ();
player.SetDataSource(filePath);
player.SetAudioStreamType(Stream.Music);
// player.SetOnCompletionListener(this);
player.Prepare();
player.Start();
player.PrepareAsync();
player.Completion += delegate {
};
} catch (Exception e) {
Console.WriteLine("OnlinePlayer()", "Exception in streaming mediaplayer e = " , e.Message.ToString());
}
}
In my case, I resolve the 2nd part of your question in this way for the listener:
player.Completion += OnPlayer_Completion;
then
private void OnPlayer_Completion(object sender, EventArgs e)
{
...your code...
}

Capture Camera Feed from EasyCap 4ch USB DVR Device using DirectShow and DirectX.Capture C#

I'm trying to capture the camera feed from an EasyCap 4 Channel USB DVR Device that i got recently
and i have bought a super Mimi Monochrome/Color Camera and connected it to the DVR Device and managed to correctly setup the device with the driver "SMI Grabber" and installed the software that comes with the Device "SuperViewer"
and i have wrote a simple windows form application that contains a PictureBox to priview the camera feed
(There is an edit in the bottom)
The Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DirectX.Capture;
namespace DirectShowWithCrossbar
{
public partial class Form1 : Form
{
private CrossbarSource crossbar;
private Filters filters;
private Capture capture;
public Form1()
{
InitializeComponent();
filters = new Filters();
capture = new Capture(filters.VideoInputDevices[0], filters.AudioInputDevices[0]);
foreach (Filter device in filters.VideoInputDevices)
{
comboBox1.Items.Add(device);
}
if (comboBox1.Items.Count > 0)
comboBox1.SelectedIndex = 0;
foreach (Filter device in filters.AudioInputDevices)
{
comboBox2.Items.Add(device);
}
if (comboBox2.Items.Count > 0)
comboBox2.SelectedIndex = 0;
foreach (Source source in capture.VideoSources)
{
comboBox3.Items.Add(source);
}
if (comboBox3.Items.Count > 0)
comboBox3.SelectedIndex = 0;
ShowPropertPagesInMenuStrip();
crossbar = (CrossbarSource)capture.VideoSource;
crossbar.Enabled = true;
capture.PreviewWindow = pictureBox1;
}
private void ShowPropertPagesInMenuStrip()
{
foreach (PropertyPage pro in capture.PropertyPages)
{
menusToolStripMenuItem.DropDownItems.Add(new ToolStripMenuItem(pro.Name));
}
}
private void button1_Click(object sender, EventArgs e)
{
capture.Cue();
capture.Start();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
capture.Stop();
capture.Dispose();
}
private void comboBox3_SelectedIndexChanged(object sender, EventArgs e)
{
capture.VideoSource = (Source)comboBox3.SelectedItem;
}
}
}
and i got a black screen in the picture box ??
and by mistake after closing my application i ran the SuperViewer application that comes with the DVR device and then open my application then my picture box began to show me the feed from the camera, strange!!! and the feed from the original software freezes !!
DirectX.Capture Example and Sources tried with the same result http://www.codeproject.com/Articles/3566/DirectX-Capture-Class-Library
and i have also used OpenCV and Touchless and i got the same result :(
Edit:
I have been searching and found that i need to get the filter (IAMCrossbar) i think that is the problem DirectShow USB webcam changing video source and after appling the changes in this link in the DirectX.Capture Wrapper i still get the same results :(
Thanks for any help in advance Yaser
If your capture device has option, to select one from multiple input interfaces, then yes, you are right about, that you needed to use IAMCrossbar.
If you want to stick to Directshow( as others have suggested OpenCV), then I would suggest,
Try building all capturing related code in a C++/CLI dll,
Build all your UI in C#.
You can take this MP3 Player Sample Project as starting point for your dll.
For capturing, AmCap is a detailed example.
What I mean is that you need to get the capturing code out of AmCap into above MP3 Player Sample dll, and expose it to your C# application.

Set capture device EmguCV

I´m using class Capture from EmguCV to take images from a WebCam.
According to the documentation of the class (http://www.emgu.com/wiki/files/2.0.0.0/html/18b6eba7-f18b-fa87-8bf2-2acff68988cb.htm), Capture has 3 constructors.
Using public Capture() its supposed to use the default camera and it works properly.
As I saw in one of the examples, seems that
public Capture(string fileName) //takes a video file as the source for the captures.
The last constructor is
public Capture(int camIndex) //which is supposed to "Create a capture using the specific camera"
I tried to use this last constructor to allow the user to choose the device in case he has more than one camera (for example, the integrated camera in a laptop or a USB cam pluged in)
My problem is I don´t know how to get a list of available devices. Tried to create captures with index from 0 to 99 and try to grab a frame expecting an exception, but it just takes a black image with the 100 captures. Also, when I use the default camera, I don´t know how to get his index.
Any help?
Edit: With the info in the answer of Shiva I got it working with this (I post it for future references):
private void onLoad(object sender, RoutedEventArgs e)
{
//Add the image processing to the dispatcher
this.Dispatcher.Hooks.DispatcherInactive += new EventHandler(dispatcherTimer_Tick);
//Get the information about the installed cameras and add the combobox items
DsDevice[] _SystemCamereas = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
Video_Device[] WebCams = new Video_Device[_SystemCamereas.Length];
for (int i = 0; i < _SystemCamereas.Length; i++)
{
WebCams[i] = new Video_Device(i, _SystemCamereas[i].Name, _SystemCamereas[i].ClassID); //fill web cam array
ComboBoxDevices.Items.Add(WebCams[i].ToString());
}
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
if (capture != null)
{
//Capture an image
Image<Bgr, byte> img = capture.QueryFrame();
//Show the image in the window
ImageOriginal.Source = ImageProcessor.ToBitmapSource(img);
}
}
private void ComboBoxDevices_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//If there is already a capture, dispose it
if (capture != null)
{
capture.Dispose();
}
//Get the selected camera
int selectedDevice = ComboBoxDevices.SelectedIndex;
try
{
//Create new capture with the selected camera
capture = new Capture(selectedDevice);
}
catch (Exception excpt)
{
MessageBox.Show(excpt.Message);
}
}
The capture object can be used to give static files as input using the following code
Capture grabber = new Emgu.CV.Capture(#".\..\..\file.avi");//can be relative path or absolute path of the video file.
For finding the list of connected web cams will need to import something like Direct Show (DirectShow.Net.dll) into the project and use the following code to retrieve the list of connected web cams .
DsDevice[] _SystemCamereas = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
Video_Device[] WebCams = new Video_Device[_SystemCamereas.Length];
for (int i = 0; i < _SystemCamereas.Length; i++)
{
WebCams[i] = new Video_Device(i, _SystemCamereas[i].Name, _SystemCamereas[i].ClassID); //fill web cam array
Camera_Selection.Items.Add(WebCams[i].ToString());
}
Check this link for the full code
http://www.emgu.com/wiki/index.php?title=Camera_Capture
This list can be populated into a combo box and each connected device can be chosen to retrieve the video input from the specific device.
Example can be found here:
http://fewtutorials.bravesites.com/entries/emgu-cv-c/level-2---use-multiple-cameras-in-one-application.
For your last question the Default Camera always has the index of 0.
So for initializing the Capture Object with default camera you will have to use the following code
Capture grabber = new Emgu.CV.Capture(0);
Examining the EMGU CV source seems to indicate that it's just passing the index off to the underlying OpenCV library, as part of the cvCreateCameraCapture (int index) function. That function is... A bit of a mess of #ifdefs, but from what I can see (and from what the comments indicate), the index is used to specify both the camera you want, and the API it should be using.
Try successively trying multiples of a hundred; each should use a different codec, attempting to use the first camera. It may be that you have one of the APIs listed compiled into your copy of OpenCV, but not working correctly on your system.
Edit: Drilling down further, it seems like it ends up at this function call, which uses the MFEnumDeviceSources function to get the list. The device you wanted is then returned out of that list (see the getDevice function a few lines higher up). So, it looks to me like the dialog you mentioned in your comment is part of Windows' MediaFoundation stuff, in which case you might want to google the wording of the message, see if some people with more experience with MF can point you in the right direction.

How to play audio file in C# with low latency/very little delay in C#?

How do I play an audio file(.mp3) in C# with very little delay? What I mean is, the file should start playing the right after user input is provided and later than that.
Also, how can I play two audio files in parallel at the same time?
Take a look at the NAudio library.
For playing multiple files at the same time, see this post.
To get minimally possible delay you need audio playback running with with no/silence data and on the event of interest you will supply real playback data onto already active device. This way you eliminate overhead of activating audio playback device that might be possibly taking place. The overhead is not that large, so you might prefer to not overcomplicate your app.
There is a choice of APIs to play audio: DirectShow.NET, NAudio in particular.
Unless you are going to work with playback device in exclusive mode (which you are unlikely to want to do), all the APIs support playback of multiple independent streams and all mixing is done for you automatically behind the scene.
I show you how I do this using DirectX AudioVideoPlayback:
public class MusicPlayer
{
private static Audio m_Audio;
private static void Loop(Object Sender, EventArgs e)
{
((Audio)Sender).SeekCurrentPosition(0d, SeekPositionFlags.AbsolutePositioning);
}
public static void Dispose()
{
if (m_Audio != null)
{
m_Audio.Stop();
m_Audio.Dispose();
m_Audio = null;
}
}
public static void Mute()
{
if ((m_Audio != null) && m_Audio.Playing)
m_Audio.Volume = -10000;
}
public static void Play(String filePath, Boolean loop)
{
if (File.Exists(filePath))
{
Dispose();
if (m_Audio == null)
m_Audio = new Audio(filePath);
else
m_Audio.Open(filePath);
if (loop)
m_Audio.Ending += Loop;
m_Audio.Volume = MusicSettings.Volume - 10000;
m_Audio.Play();
}
}
public static void Unmute()
{
if (m_Audio != null)
m_Audio.Volume = MusicSettings.Value - 10000;
}
}
You can start from this snippet.

Categories