I'm basically asking the same thing that was asked here, however, that question was asked 8 years ago and the answer is no longer applicable to UWP.
I have a audio stream with http://someurl.com/stream that streams in audio/ogg format. I would like to be able to play that from an UWP app.
I see the NAudio library recommended a lot (after all, it's used in the above example), however it's very larger and has fairly lackluster documentation and very few up-to-date examples (they used to have a streaming example, but from what I'm able to download off Codeplex, it was replaced with a regular local-file player example). I'm not experience enough to make sense of the little documentation and example code they do have.
I'm honestly not even sure where to begin. I've never handled a stream like this (or any stream). Maybe the NAudio library isn't the way to go?
Code would be appreciated, but even pointers to sources where I could read up on playing such stream would be very helpful as my google-fu has failed me.
Thank you.
EDIT:
private void PlayMedia() {
System.Uri manifestUri = new Uri("http://amssamples.streaming.mediaservices.windows.net/49b57c87-f5f3-48b3-ba22-c55cfdffa9cb/Sintel.ism/manifest(format=m3u8-aapl)");
var mediaPlayer = new Windows.Media.Playback.MediaPlayer();
~~~~~~~~~~~~ -> "'Media Player' does not contain a constructor that takes 0 arguments."
mediaPlayer.Source = MediaSource.CreateFromUri(manifestUri);
mediaPlayer.Play();
}
but I can't get the MediaPlayer class to work. It says for example the x.Play() doesn't exist.
You have not posted your code segment. So I could not locate the problem of Visual Studio alerting "doesn't exist" accurately. If you want to use "MediaPlayer" class please add Windows.Media.Core and Windows.Media.Playback namespace at first. And you could reference the following code implementing a basic mediaplayer.
using Windows.Media.Core;
using Windows.Media.Playback;
......
private void PlayMedia()
{
System.Uri manifestUri = new Uri("http://amssamples.streaming.mediaservices.windows.net/49b57c87-f5f3-48b3-ba22-c55cfdffa9cb/Sintel.ism/manifest(format=m3u8-aapl)");
var mediaPlayer = new MediaPlayer();
mediaPlayer.Source = MediaSource.CreateFromUri(manifestUri);
mediaPlayer.Play();
}
The error message of Media Player does not contain a constructor that takes 0 arguments is means that there is no constructor with no arguments in the MediaPlayer class. Please try use the full name of constructor with namespace.
var mediaPlayer = new Windows.Media.Playback.MediaPlayer();
Related
Using an android scanner device, running KitKat.
Using Xamarin in Visual Studio Enterprise 2017, 15.9.9.
I need to generate a "Success" or "Error" sound, based on the content of the scanned barcode.
I have two files: "Success.mp3" and "Error.wav", neither of which will play.
Since this should be a very simple process, I am trying to use Android's MediaPlayer class, rather than add some NuGet package.
I am using Dependency Injection to properly run the Android code, since Xamarin does not have any sort or media API.
I instantiate Android's MediaPlayer as variable "player", and it does successfully instantiate, but as soon as I attempt to do anything with it, it throws a Null Exception error and the value of "player" displays as Null.
I have been experimenting with different ways to do this and have copies of the sound files stored both in the Assets folder, and the Resources/Raw folder (see below).
Here is my method:
public void PlaySound(string soundType) {
var filename =
global::Android.App.Application.Context.Assets.OpenFd(soundType);
if (player == null) {
MediaPlayer player = new MediaPlayer();
}
//This is where the error happens
player.SetDataSource(filename);
player.Prepare();
player.Start();
}
I have also tried the last three lines as the following, with the same result:
player.Prepared += (s, e) => {
player.Start();
};
player.SetDataSource(filename.FileDescriptor, filename.StartOffset,
filename.Length);
player.Prepare();
I have also attempted to utilize what so many people demonstrate as the way to do this, but it does not work for me. This is where the file must be stored in Resources/Raw:
player = MediaPlayer.Create(global::Android.App.Application.Context,
Resource.Raw.someFileName);
Whatever value that you use for "someFileName", all Visual Studio gives you is "'Resource.Raw' does not contain a definition for 'someFileName'".
Resource.designer.CS does contain entries for both files:
public const int Error = 2131230720;
public const int Success = 2131230721;
Expected results: sound, or some meaningful error message that puts me on the right path.
I am still relatively new to Xamarin and am probably missing something that would be obvious to veteran eyes. I have tried so many other things, most of which are not mentioned here, grasping for some straw. This should be simple, but is proving otherwise. Thank you for any help that you can provide.
This program is an audio visualizer for an rgb keyboard that listens to windows' default audio device. My audio setup is a bit more involved, and I use way more than just the default audio device. For instance, when I play music from Winamp it goes through the device Auxillary 1 (Synchronous Audio Router) instead of Desktop Input (Synchronous Audio Router) which I have set as Default. I'd like to be able change the device that the program listens to for the visualization.
I found in the source where the audio device is declared; Lines 32-36 in CSCoreAudioInput.cs:
public void Initialize()
{
MMDevice captureDevice = MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console);
WaveFormat deviceFormat = captureDevice.DeviceFormat;
_audioEndpointVolume = AudioEndpointVolume.FromDevice(captureDevice);
}
The way that I understand it from the documentation, the section MMDeviceEnumerator.DefaultAudioEndpoint(DataFlow.Render, Role.Console) is where Windows gives the application my default IMMEndpoint "Desktop Input."
How would I go about changing DefaultAudioEndpoint?
Further Reading shows a few ways to get an IMMDevice, with DefaultAudioEnpoint being one of them. It seems to me that I'd have to enumerate the devices, and then separate out Auxillary 1 (Synchronous Audio Router) using PKEY_Device_FriendlyName. That's a bit much for me, as I have little to no C# experience. Is there an easier way to go about choosing a different endpoint? Am I on the right track? or am I missing the mark completely?
Also, what is the difference between MMDevice and IMMDevice? The source only seems to use MMDevice while all the Microsoft documentation references IMMDevice.
Thanks.
I DID IT!
I've found why the program uses MMDevice rather than IMMDevice. The developer has chosen to use the CSCore Library rather than Windows' own Core Audio API.
From continued reading of the CSCore MMDeviceEnumerator Documentation, it looks like I'll have to make a separate program that outputs all endpoints and their respective Endpoint ID Strings. Then I can substitute the DefaultAudioEndpoint method with the GetDevice(String id) method, where String id is the ID of whichever Endpoint I chose from the separate program.
To find the the Endpoint I wanted, I wrote this short program to find all the info I wanted:
static void Main(string[] args)
{
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
Console.WriteLine($"\nNumber of active Devices: {collection.GetCount()}");
int i = 0;
foreach (MMDevice device in collection){
Console.WriteLine($"\n{i} Friendly name: {device.FriendlyName}");
Console.WriteLine($"Endpoint ID: {device.DeviceID}");
i++;
}
Console.ReadKey();
}
This showed me that the Endpoint I wanted was item number 3 (2 in an array) on my list, and instead of using GetDevice(String id) I used ItemAt(int deviceIndex).
MMDeviceEnumerator enumerator = new MMDeviceEnumerator();
MMDeviceCollection collection = enumerator.EnumAudioEndpoints(DataFlow.Render,DeviceState.Active);
MMDevice captureDevice = collection.ItemAt(2);
However in this case, the program was not using captureDevice to bring in the audio data. These were the magic lines:
_capture = new WasapiLoopbackCapture(100, new WaveFormat(deviceFormat.SampleRate, deviceFormat.BitsPerSample, i));
_capture.Initialize();
I found that WasapiLoopbackCapture uses Windows' default device unless changed, and the code was using DefaultAudioEndpoint to get the properties of the default device. So I added
_capture.Device = captureDevice;
//before
_capture.Initialize();
And now the program properly pulls the audio data off of my non-default audio endpoint.
I had been asked to solve a similar type of problem this week. Although there are a few librarys to do this I was specifically asked to do this for "non ish" programmers so I developed this in PowerShell.
Powershell default audio device changer - Github
Maybe you can alter it to your needs.
I am going crazy right now. Since all other questions are several years old and the MonoTorrent developers have gone MIA I really need your help.
What I am really stuck with is parsing the magnet link and downloading it.
This is my code:
public static void DownloadTorrent(string magnetLink)
{
MagnetLink link = new MagnetLink(magnetLink);
//URL stores the magnetlink
EngineSettings settings = new EngineSettings();
settings.AllowedEncryption = EncryptionTypes.All;
settings.SavePath = destination;
string torrentFilePath = torrentDestination;
if (!Directory.Exists(settings.SavePath))
Directory.CreateDirectory(settings.SavePath);
if (!Directory.Exists(torrentFilePath))
Directory.CreateDirectory(torrentFilePath);
//Create a new engine, give it some settings and use it.
ClientEngine engine = new ClientEngine(settings);
engine.ChangeListenEndpoint(new IPEndPoint(IPAddress.Any, 6969));
TorrentManager manager = new TorrentManager(link, engine.Settings.SavePath, new TorrentSettings(), torrentFilePath);
engine.Register(manager);
manager.Start();
Console.ReadLine();
}
And my magnet link is: "magnet:?xt=urn:btih:c6df2f47d033d54b054cafe7ef683ba167222d92&dn=Windows+XP+Professional+SP3+-+Activated&tr=udp%3A%2F%2Ftracker.leechers-paradise.org%3A6969&tr=udp%3A%2F%2Fzer0day.ch%3A1337&tr=udp%3A%2F%2Fopen.demonii.com%3A1337&tr=udp%3A%2F%2Ftracker.coppersurfer.tk%3A6969&tr=udp%3A%2F%2Fexodus.desync.com%3A6969"
Now an error throws on the magnet link saying "No such host is known and referring to udp://exodus.desync.com:6969/"(Visual Studio is on swedish so that might not be a literal translation).
Visual Studio is marking tracker = new UdpClient(announceUrl.Host, announceUrl.Port); as the error source and it's located inside one of MonoTorrent's code files; UdpTracker.cs
I am trying to make a simple application and I am just stuck on this part.
Any help is greatly appreciated. It's one of my first times posting here so if I missed to mention anything just tell me and I will add it.
Thanks on forehand! Also pardon my english, I am not a native speaker.
Update: If you know another way of solving this even without MonoTorrnet - I will take any help I can.
The question says it all.
I would like to create the simplest possible VU-meter example, using the new UWP Media Graph API, but so far, I haven't found any good examples.
There are a couple of questions in this:
I am using the "normal" code to enumerate my microphones:
var deviceInformation = await DeviceInformation.FindAllAsync(MediaDevice.GetAudioCaptureSelector());
However, when I create an AudioGraphSettings object, I cannot find a property to pass the device found. There is a property named DesiredRenderDeviceAudioProcessing however, I'm not sure I understand it's purpose.
Following the best examples I've found, I proceed to create a graph, and use that to get an InputNode as such:
var creationResult = await AudioGraph.CreateAsync(settings);
if (creationResult.Status != AudioGraphCreationStatus.Success)
return;
_graph = creationResult.Graph;
var inputNodeCreationResult = await _graph.CreateDeviceInputNodeAsync(Windows.Media.Capture.MediaCategory.Media);
if (inputNodeCreationResult.Status != AudioDeviceNodeCreationStatus.Success)
{
DestroyGraph();
return;
}
_inputNode = inputNodeCreationResult.DeviceInputNode;
From here on, I'm running blind. Not finding any good tutorials, examples or documentation to help me.
I am only interested in sound level (dB), not the waveform. Is there anyone that can help me complete this, or point me to some decent documentation?
"Scenario 2: Device Capture" from the Windows Universal Samples - Audio Creation project should provide some guidance. From your code it looks like you're on track. Might just be a case of adding the following:
_frameOutputNode = _graph.CreateFrameOutputNode();
_frameOutputNode.Start();
_graph.QuantumProcessed += Graph_QuantumProcessed;
_graph.Start();
And using the Graph_QuantumProcessed callback to analyse the AudioFrame provided by a call to _frameOutputNode.GetFrame().
Hope it helps.
I'm an experienced MFC programmer of many years, who for the more recent years has been developing commercial apps in Objective C for Mac and iOS - I'm trying to get up to speed with .Net and C# (as I'm soon going to be required to convert one of my commercial apps from Mac to PC).
I've now worked my way through a couple of books and as an exercise to get more familiar with .Net (and C#) I've decided to have a go at converting one of my none commercial apps to .Net as a learning exercise and all is going well (interface is working, data structures all good) but I need to be able to play audio.
My Mac app generates audio from a series of mathematical formula - imagine a wave generator - not quite the same but similar. On the Mac I generate the audio as 16 bit signed raw audio, use Core Audio to setup audio output routing and then get a callback whenever a new buffer of audio is required for the audio routing (so I can generate the audio on the fly).
I need to do the same on the PC. Unfortunately I find MSDN documentation to be a case of "Can't see the wood for the trees" as there is such a vast amount of documentation. I can find classes that will let me load and play mp3/wav etc files, but I need to generate the audio realtime. Can anyone point me in the right direction to find something that will allow me to fill buffers on the fly as it plays them?
Thx
I have used this sample in several projects with good results. It is basically a .Net wrapper for Windows Waveform Audio API using P/Invoke.
Other choices:
NAudio
Sound Player class from .Net framework
I have created a class that can play audio given Stream derivate as an input. So if you are able to pack your sound-generator into the Stream compatible interface, it could be suitable for you.
How I did it - I used unmanaged waveOut* methods from old Windows multimedia API, and handled the playback from there.
Other options - that I am aware of - use waveOut directly, from this: http://windowsmedianet.sourceforge.net/ or write your own DirectShow source filter, but that might be too complicated, since it has to be written in c++.
If you are interested in giving my component a try, I can make it available to you at no charge, since I need it beta tested (I only used it in several of my projects).
EDIT:
Since there are 6 upvotes to the question, I am offering my component free of charge (if you find useful) here: http://dl.dropbox.com/u/10020780/SimpleAudioPlayer.zip
Maybe you can reflect on it :)
I use Audiere to accomplish this and find it works very well.
It's a C++ lib really, but there are a set of bindings available for C#.
For more info, see the question I asked.
You should have a look at FMOD which allows this kind of operation and much more. It is also cross platform which can be interested if you are also working on a mac.
Alvas.Audio has 3 audio players: Player
player.FileName = "123.mp3";
player.Play();
PlayerEx
public static void TestPlayerEx()
{
PlayerEx plex = new PlayerEx();
plex.Done += new PlayerEx.DoneEventHandler(plex_Done);
Mp3Reader mr = new Mp3Reader(File.OpenRead("in.mp3"));
IntPtr format = mr.ReadFormat();
byte[] data = mr.ReadData();
mr.Close();
plex.OpenPlayer(format);
plex.AddData(data);
plex.StartPlay();
}
static void plex_Done(object sender, DoneEventArgs e)
{
if (e.IsEndPlaying)
{
((PlayerEx)sender).ClosePlayer();
}
}
and RecordPlayer
public static void TestRecordPlayer()
{
RecordPlayer rp = new RecordPlayer();
rp.PropertyChanged += new PropertyChangedEventHandler(rp_PropertyChanged);
rp.Open(new Mp3Reader(File.OpenRead("in.mp3")));
rp.Play();
}
static void rp_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case RecordPlayer.StateProperty:
RecordPlayer rp = ((RecordPlayer)sender);
if (rp.State == DeviceState.Stopped)
{
rp.Close();
}
break;
}
}