Cross Platform C# Media API - c#

I'm trying to define a VideoFile in mono/.net object such that I can call
var file = new VideoFile(filepath);
file.VideoDuration
Is there a library (os or commercial) which will work across platforms mono/.net which can provide information such as VideoDuration. The only though I have had on this currently is to wrap ffmpeg.exe and read the console out-stream.

GStreamer is good option, it's a cross platform multimedia framework. And there are bindings that would meet your needs: access the information you require (length of a video file) via a .NET API: GStreamerSharp.
Indeed, we actually use it in the Banshee Project, a media player written in C# (which is the default music player bundled in Ubuntu).
BTW, GStreamer is architected in a way that codecs are plugins, so you have an abstraction between the internals of them (i.e. ffmpeg) which other plugins could fulfill depending on your licensing/format needs.

Related

Audio Framework for Mac and Windows

I realize I asked a question similar to this before, but the planning on what I want to do has come some way, and the parameters have become a bit different.
Basically, I'm looking for the best option for decoding and outputting audio on both Mac and Windows. Ideally, there will be no differences in needed code between the two platforms. I just want to be able to pass it a file path or HTTP URL and have it play the audio with the ability to pause, seek, etc.
It must be able to decode MP3 and AAC out of the box with no dependencies on the OS (like Phonon for Qt which is entirely dependent on the OS). Any other codecs beyond that would be a very nice bonus.
I've looked at things like libavcodec, which supposedly can decode about anything, but haven't been able to figure out how to get it to work. So far it seems that libraries I've seen are also ready for Mac and Linux or Windows and Linux but not Mac and Windows.
It does not need to be open source, but if it is needs to be usable in commercial products. I'm OK with licensing something as long as it's not too expensive and easy to use.
Finally, while C/C++ would be preferred, if there's something that would work with C#/Mono, that's OK too.
Any suggestions on something that would work for this?
I've created a C++ audio library for Mac and Windows named "Crosstalk".
Crosstalk is a C++ audio engine that allows you to create and route audio systems in real-time. The engine takes care of all the audio routing and gives you a simple platform for creating system components (E.g. "Mp3 Decoder" component connected to a "Low-Pass Filter" connected to an "Audio Device" and "File Recorder").
It's very easy to use. Here's an example of how to play an mp3 file (These components are provided with the engine):
XtSystem system;
XtMp3Decoder mp3Decoder;
XtAudioDevice audioDevice;
long md = system.addComponent(&mp3Decoder);
long ad = system.addComponent(&audioDevice);
system.connOutToIn(md,0,ad,0);
system.connOutToIn(md,1,ad,1);
mp3Decoder.loadFile("../05 Tchaikovski-Swan Lake-Scene.mp3");
mp3Decoder.play();
Included with Crosstalk is example Xcode and Visual Studio projects.
You can download Crosstalk and check out the API documentation and licensing details here: http://www.adaptaudio.com/Crosstalk
EDIT (01-12-2012):
Crosstalk has been replaced by an open-source project called "DSPatch". DSPatch is essentially an upgraded version of the routing engine behind Crosstalk that is no longer limited to only audio processing. DSPatch allows you to create and route almost any type of process chain imaginable, and free for personal AND proprietary use :)
decode MP3 and AAC out of the box
I'm not aware of any audio library that does this so easilly. The problem is the license issue regarding MP3 decoding.
I discuss some options on this post, and they are good for Windows/Mac OS X, but I'm not sure if they have C# bindings.
If you are willing to write the bindings yourself, you might be interested at libaudiodecoder:
A C++ cross platform MP3/AAC/WMA/WAV decoder.
It comes with an example that shows how to play a song on Windows/Mac through PortAudio.

Streaming Music from iPad/iPhone/iPod Touch to PC (AirTunes) in .NET

I saw the projects shairport and shairport4w which stream music from an iDevice (called AirTunes/AirPlay by Apple) to a computer. I wanted to do the same for my media player. Those two projects are in C/C++/Perl and so I can't port them to C#/VB.
Can anyone explain me how the AirTunes protocol works and how do I implement it in .NET?
This is old but may be a good starting point;
JustPort
First version of Airfoil was based on this
You have 2 options:
port the C/C++ code to .NET / C#
use the C/C++/Perl code/library via DllImport or via Process.Start from .NET

What APIs do I need to look at to code my own windows drive letter

I was thinking of messing around with my own file system code, as a learning exercise. To start with this could be a RAM drive, or just mounted within a file on another drive. Questions:
What windows APIs would I need to program to implement my own drive letter (eg an M: with my system)
Where is the documentation for these APIs?
Can you implement them using C#?
NB:
I know there are other Ram drive implementations out there - I don't need a list of them.
I've tried googling, but found it very hard to find the right search terms.
I'm not fussy for now about which version of windows, any version is fine as I'm developing using Windows 7, but I hope that version for earlier Windows will still work
Take a look at the IFS (Installable Filesystem) Kit.
You're talking about writing a filesystem driver. The basic model is that your code gets loaded into the NT kernel and processes IRPs.
No, you can't do it in C#.
You need to look at the Windows DDK - now called "WDK" apparently. The WDK includes the Installable File Systems (IFS) kit. See here:
Installable File Systems (IFS) kit
Device drivers on Windows are written in C/C++. As far as I know there is no way to implement a file system driver in .NET. There is no CLR in kernel space.
EDIT: asveikau beat me to it...
From this answer to a similar question: how to map a software as a Drive?
Have a look at Dokan. It looks like a nice scriptable wrapper to low-level filesystem drivers. Like FUSE on Linux.
The docs page mention that you can use it to write filesystem code in C#, VB, C++ and even Ruby! Since it exposes itself as a .Net library I'm guessing you can do it in any language running on the CLR as well such as IronPython or F#.
Depending on what you need (implement a file system or just a virtual disk with existing file system) you can use one of our virtual storage products: Callback File System and CallbackDisk respectively.
The difference is that CallbackDisk emulates a disk device (so you can mount, for example, ISO image there), and Callback File System lets you build your own file system (eg. distributed, or just remotely stored)
.NET APIs are available in both products.

Which audio library to use?

I want to build a .Net application for processing audio, and distribute it using ClickOnce deployment. I need access to a raw audio pipeline. Which audio library should I be using? I've heard the managed libraries for DirectSound are a dead end. I need as little as possible to be installed on the client's machine. Anything outside of the ClickOnce process isn't going to work.
NAudio might be a possibility, but isn't there potentially a separate driver install? There's also SlimDX.
It's a shame -- the managed DirectX libraries seem to work nicely and from what I've read, DirectX can be included in the ClickOnce install.
BASS : http://www.un4seen.com/
with Bass.Net is quite simple to use.
Although not free, Alvas.Audio may be worth looking at.
OpenTK has an OpenAL implementation, but I'm not sure how it behaves with ClickOnce and it lacks reading/writing complex audio file formats(such as vorbis).

How can I play compressed sound files in C# in a portable way?

Is there a portable, not patent-restricted way to play compressed sound files in C# / .Net? I want to play short "jingle" sounds on various events occuring in the program.
System.Media.SoundPlayer can handle only WAV, but those are typically to big to embed in a downloadable apllication. MP3 is protected with patents, so even if there was a fully managed decoder/player it wouldn't be free to redistribute. The best format available would seem to be OGG Vorbis, but I had no luck getting any C# Vorbis libraries to work (I managed to extract a raw PCM with csvorbis but I don't know how to play it afterwards).
I neither want to distribute any binaries with my application nor depend on P/Invoke, as the project should run at least on Windows and Linux. I'm fine with bundling .Net assemblies as long as they are license-compatible with GPL.
[this question is a follow up to a mailing list discussion on mono-dev mailing list a year ago]
I finally revisited this topic, and, using help from BrokenGlass on writing WAVE header, updated csvorbis. I've added an OggDecodeStream that can be passed to System.Media.SoundPlayer to simply play any (compatible) Ogg Vorbis stream. Example usage:
using (var file = new FileStream(oggFilename, FileMode.Open, FileAccess.Read))
{
var player = new SoundPlayer(new OggDecodeStream(file));
player.PlaySync();
}
'Compatible' in this case means 'it worked when I tried it out'. The decoder is fully managed, works fine on Microsoft .Net - at the moment, there seems to be a regression in Mono's SoundPlayer that causes distortion.
Outdated:
System.Diagnostics.Process.Start("fullPath.mp3");
I am surprised but the method Dinah mentioned actually works. However, I was thinking about playing short "jingle" sounds on various events occurring in the program, I don't want to launch user's media player each time I need to do a 'ping!' sound.
As for the code project link - this is unfortunately only a P/Invoke wrapper.
I neither want to distribute any
binaries with my application nor
depend on P/Invoke, as the project
should run at least on Windows and
Linux. I'm fine with bundling .Net
assemblies as long as they are
license-compatible with GPL.
Unfortunatly its going to be impossible to avoid distributing binaries, or avoid P/Invoke. The .net class libraries use P/Invoke underneath anyway, the managed code has to communicate with the unmanage operating system API at some point, in order to do anything.
Converting the OGG file to PCM should be possible in Managed code, but because there is no Native Support for Audio in .net, you really have 3 options:
Call an external program to play the sound (as suggested earlier)
P/Invoke a C module to play the sound
P/Invoke the OS APIs to play the sound.
(4.) If you're only running this code on windows you could probably just use DirectShow.
P/Invoke can be used in a cross platform way
http://www.mono-project.com/Interop_with_Native_Libraries#Library_Names
Once you have your PCM data (using a OGG C Lib or Managed Code, something like this http://www.robburke.net/mle/mp3sharp/ of course there are licencing issues with MP3), you will need a way to play it, unfortunatly .net does not provide any direct assess to your sound card or methods to play streaming audio. You could convert the ogg files to PCM at startup, and then use System.Media.SoundPlayer, to play the wav files generated. The current method Microsoft suggests uses P/Invoke to access Sound playing API in the OS http://msdn.microsoft.com/en-us/library/ms229685.aspx
A cross platform API to play PCM sound is OpenAL and you should be able to play (PCM) sound using the c# bindings for OpenAL at www.taoframework.com, you will unfortunatly need to copy a number of DLL and .so files with your application in order for it to work when distributed, but this is, as i've explained earlier unavoidable.
Calling something which is located in 'System.Diagnostics' to play a sound looks like a pretty bad idea to me. Here is what that function is meant for:
//
// Summary:
// Starts a process resource by specifying the name of a document or application
// file and associates the resource with a new System.Diagnostics.Process component.
//
// Parameters:
// fileName:
// The name of a document or application file to run in the process.
//
// Returns:
// A new System.Diagnostics.Process component that is associated with the process
// resource, or null, if no process resource is started (for example, if an
// existing process is reused).
//
// Exceptions:
// System.ComponentModel.Win32Exception:
// There was an error in opening the associated file.
//
// System.ObjectDisposedException:
// The process object has already been disposed.
//
// System.IO.FileNotFoundException:
// The PATH environment variable has a string containing quotes.
i think you should have a look a fmod, which is the mother of all audio api
please feel free to dream about http://www.fmod.org/index.php/download#FMODExProgrammersAPI
The XNA Audio APIs work well in .net/c# applications, and work beautifully for this application. Event-based triggering, along with concurent playback of multiple sounds. Exactly what you want. Oh, and compression as well.
Well, it depends on a patent-related laws in a given country, but there is no way to write a mp3 decoder without violating patents, as far as i know. I think the best cross-platform, open source solution for your problem is GStreamer. It has c# bindings, which evolve rapidly. Using and building GStreamer on Windows is not an easy task however. Here is a good starting point. Banshee project uses this approach, but it is not really usable on windows yet (however, there are some almost-working nightly builds). FMOD is also a good alternative. Unfortunately, it is not open source and i find that its API is somehow C-styled.
There is a pure C# vorbis decoder available that is open source:
http://anonsvn.mono-project.com/viewvc/trunk/csvorbis/
Not sure if this is still relevant. Simplest solution would be to use NAudio, which is a managed open source audio API written in C#. Another thing to try would be utilizing ffmpeg, and creating a process to ffplay.exe (the right binaries are under shared builds).
There is no way for you to do this without using something else for your play handling.
Using the System.Diagnostic will launch an external software and I doubt you want that, right? You just want X sound file to play in the background when Y happens in your program, right?
Voted up because it looks like an interesting question. :D

Categories