how do i get Android.Media.SetPreferredDevice() to work - c#

So making a mobile application that works on UWP, IOS and Android but since not all librarys work on every platform I'm using the library based on what device is used by
if (Device.RuntimePlatform == Device.Android) { }
And I'm currently only working on the Android part of the application.
I'm using Android.Media to play a single audio file out of multiple speakers. And to do that I'm using a Picker that has the available audio output devices. This part works.
But I'm getting a error while trying to select the PreferredDevice:
Java.Lang.NoSuchMethodError: 'no non-static method "Landroid/media/MediaPlayer;.setPreferredDevice(Landroid/media/AudioDeviceInfo;)Z"'
The code line that is giving the error is:
mediaPlayer1.SetPreferredDevice(audioDeviceInfo);
the full method that is being run is:
newoutput.SelectedIndexChanged += (changed, args) =>
{
Context context = Android.App.Application.Context;
AudioManager audioMan = (AudioManager)context.GetSystemService(Context.AudioService);
AudioDeviceInfo audioDeviceInfo = audioMan.GetDevices(GetDevicesTargets.Outputs)[newoutput.SelectedIndex];
mediaPlayer1.SetPreferredDevice(audioDeviceInfo);
};
I can't find many examples that use the method and they don't usually go with a mediaplayer that is created by button press.

You can use this code
private AudioDeviceInfo findAudioDevice(int deviceType) {
AudioManager manager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
AudioDeviceInfo[] adis = manager.getDevices(GET_DEVICES_OUTPUTS);
for (AudioDeviceInfo adi : adis) {
if (adi.getType() == deviceType) {
return adi;
}
}
return null;
}
Then set your input:
audioRecord.setPreferredDevice(findAudioDevice([newoutput.SelectedIndex]));

Related

Detecting currently worn HMD using Windows Mixed Reality

I am working with Unity and the Mixed Reality Toolkit. My issue is that "HP Reverb G2" is not detected using Windows Mixed Reality, but it works if I parse with SteamVR. My goal is to detect if the headset is on my head without using SteamVR.
My current solution, which doesn't work, is as follows:
public static bool IsHMDMounted()
{
if (headDevice == null || headDevice.isValid == false)
{
headDevice = InputDevices.GetDeviceAtXRNode(XRNode.Head);
}
if (headDevice != null)
{
bool presenceFeatureSupported = headDevice.TryGetFeatureValue(CommonUsages.userPresence, out bool userPresent);
if (headDevice.isValid && presenceFeatureSupported)
{
return userPresent;
}
else
{
return false;
}
}
else
{
return false;
}
}
There is a discussion related to this issue on the Unity forums - Question - OpenXR -- Is it no longer possible to get descriptive device names? - Unity Forum.
Referring to this thread, it seems that Unity does not expose the device information provided by Open XR, but you can get this information by intercepting the API of Open XR according to the method mentioned in the thread - https://forum.unity.com/threads/openxr-is-it-no-longer-possible-to-get-descriptive-device-names.1051493/#post-8275923.

Xamarin Mac FFmpeg launch path not accessible

I have a Xamarin Forms project with Mac support and I am trying to implement FFmpeg, so I have downloaded the Static build from its official page and added it as in the resources folder of the Mac project with the build action in Content, then I have created a service that will basically remove the audio from a video that I indicate in a path with a FFmpeg command, to do the service I have based on the following answer and I have adapted it to C #:
https://stackoverflow.com/a/37422688/8496520
The problem is that when I try to execute the command I get the following error:
"NSInvalidArgumentException: launch path not accessible"
And I can't find out why this happens, I use the following code in the service (The error occurs when calling the Launch () method of the NSTask):
public void ExecuteFFmpeg()
{
try
{
var launchPath = NSBundle.MainBundle.PathForResource("ffmpeg", ofType: "");
var compressTask = new NSTask();
compressTask.LaunchPath = launchPath;
compressTask.Arguments = new string[] {
"-i",
"downloads/test.mp4",
"-c",
"copy",
"-an",
"nosound.mp4" };
compressTask.StandardInput = NSFileHandle.FromNullDevice();
compressTask.Launch();
compressTask.WaitUntilExit();
}
catch (Exception ex)
{
}
I have also uploaded the project to GitHub in case someone needs to consult the repository in its entirety: https://github.com/nacompllo/FFmpegSample
If you are not tied to NSTask you could use CliWrapper instead.
public static async ValueTask FfmpegRemoveAudio(string ffmpegPath, string inputFilePath, string outputFilePath)
{
await Cli.Wrap(ffmpegPath).WithArguments(new[] { "-i", inputFilePath, "-c", "copy", "-an", outputFilePath }).ExecuteAsync();
}
Beside of CliWrapper I also tested FfmpegCore and FFmpget.NET that also threw some similar exceptions like you describe. I have no glue, why they behavior different. See the complete working POC for details.

How do I play the Windows Notification sound? (It is not defined in System.Media.SystemSounds)

When using System.Media, there is something called SystemSounds where you can easily play a couple of operating system sounds:
System.Media.SystemSounds.Asterisk.Play();
System.Media.SystemSounds.Beep.Play();
System.Media.SystemSounds.Exclamation.Play();
System.Media.SystemSounds.Hand.Play();
System.Media.SystemSounds.Question.Play();
Unfortunately, there are only these five options, and in Windows 10, three of them are the same while one of them doesn't even play anything.
What I really want to do is play the Notification sound, as defined in the Sound panel (seen here):
Does anyone know how to do this?
Solution found. Code here:
using System.Media;
using Microsoft.Win32;
public void PlayNotificationSound()
{
bool found = false;
try
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(#"AppEvents\Schemes\Apps\.Default\Notification.Default\.Current"))
{
if (key != null)
{
Object o = key.GetValue(null); // pass null to get (Default)
if (o != null)
{
SoundPlayer theSound = new SoundPlayer((String)o);
theSound.Play();
found = true;
}
}
}
}
catch
{ }
if (!found)
SystemSounds.Beep.Play(); // consolation prize
}
You can browse the keys in the registry editor to see the other sounds. Also, this example is coded to work for Windows 10, and I'm not sure what the registry structure is for other versions of Windows, so you'll need to double check what OS the user is using if you're trying to code for multiple platforms.

InstalledRecognizers() doesn't run

I'm trying to integrate Microsoft Speech Platform with Kinect and I've come across with the method: SpeechRecognitionEngine.InstalledRecognizers(), which doesn't run at all. When I call the method from my class the execution doesn't continue. I'm using this method to get the Kinect Recognizer.
What's the problem? This is the piece of code where I'm using the method InstalledRecognizers():
RecognizerInfo obtenerReconocedorKinect()
{
String details;
System.Collections.ObjectModel.ReadOnlyCollection<RecognizerInfo> recs = SpeechRecognitionEngine.InstalledRecognizers();
foreach (RecognizerInfo recInfo in recs)
{
if (recInfo.AdditionalInfo.ContainsKey("Kinect"))
{
details = recInfo.AdditionalInfo["Kinect"];
if (details == "True" && recInfo.Culture.Name == "en-US")
{
return recInfo;
}
}
}
return null;
}
Thanks in advance.
So the problem was:
a System.Runtime.InteropServices.COMException in Microsoft.Speech.dll with the following error: Not registered class REGDB_E_CLASSNOTREG
The issue has been solved by reinstalling the Kinect SDK.

Can't open a mpg-File for capture using EmguCV with C#

I'm trying to open a mpg-File using emguCV. I use the following code:
if (instance == null)
{
lock (m_lock)
{
try
{
instance = new Capture(0); // capture from camera works fine if a camera is connected
}
catch (NullReferenceException)
{
String sFileName = #"C:\tmp\MarkerMovie.mpg";
try
{
if (File.Exists(sFileName))
{
instance = new Capture(sFileName); // here the exception is thrown
}
else
{
MessageBox.Show("No Camera and no Video-File found");
}
}
catch (NullReferenceException)
{
MessageBox.Show("Couldn't open Video: "+sFileName);
}
}
}
}
If a webcam is connected everything works fine, but when I unplug the webcam the line instance = new Capture(sFileName); throws a NullReferenceException:
Message = "Unable to create capture from C:\tmp\MarkerMovie.mpg"
I debugged and found the reason is in the constructor of capture. The following command always returns a Null-Pointer:
_ptr = CvInvoke.cvCreateFileCapture(fileName);
I could open the same video using C++ using this code:
cap = cvCaptureFromFile("C:\\tmp\\MarkerMovie.mpg");
I'm new to openCV, so I'm not sure which information you need to help me. I installed emguCV yesterday from http://sourceforge.net/projects/emgucv/ on a Windows XP computer. The installer-version is x86_2.3.0.1416. I included opencv_core231.dll, opencv_highgui231.dll and opencv_imgproc231.dll to my project.
Does somebody know how I can make this code working?
Let me know if you need more information.
Thanks.
I had the same problem and adding the opencv_ffmpeg.dll to the project seems to solve it. (Found in the bin directory in the Emgu CV directory) I have tried it on the project that you posted and it seems to be working too. Hope it helps.
With EmguCV in C#, you need to put the opencv_ffmpeg.dll, for example: opencv_ffmpeg2410.dll, be careful if you have x86 or 64 bits

Categories

Resources