The Windows Runtime (WinRT) provides the MediaStreamSource and MediaTranscoder classes to encode audio/video streams in Universal Phone/Windows Store apps. Those classes are not limited to Store apps though: they can also be used in Desktop apps (command line, WPF, etc.) via a few tricks.
The first trick is to enable Windows Runtime support in Desktop C# projects. Toward that end, open the .csproj file in your favorite text editor and:
<PropertyGroup>
add:<TargetPlatformVersion>8.1</TargetPlatformVersion>
<PropertyGroup>
also bump the framework version to 4.5.1:<TargetFrameworkVersion>v4.5.1</TargetFrameworkVersion>
<ItemGroup>
containing <Reference>
elements add:<Reference Include="Windows" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.InteropServices.WindowsRuntime" />
<Reference Include="System.Runtime.WindowsRuntime" />
Then save, go to Visual Studio, and reload the project (Visual Studio automatically prompts for that).
The second trick is to work around WinRT APIs which are tied to Store apps. For instance most of StorageFile and StorageFolder work in Desktop apps but KnownFolders has issues. The work around is to get paths to known folders using Environment.GetFolderPath() first and then pass those paths to StorageFolder.GetFolderFromPathAsync() to open a StorageFolder
:
StorageFolder musicFolder = await StorageFolder.GetFolderFromPathAsync(
Environment.GetFolderPath(Environment.SpecialFolder.MyMusic)
);
Besides that, the code to encode audio is the same in Desktop apps as in Store apps. First create a MediaStreamSource
specifying the input audio format via AudioEncodingProperties and generating audio data in the SampleRequested event handler:
var source = new MediaStreamSource(
new AudioStreamDescriptor(
generator.EncodingProperties
)
);
source.SampleRequested += (MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args) =>
{
args.Request.Sample = generator.GenerateSample();
};
Then create a MediaTranscoder
, passing the media source, a destination stream, and a destination encoding profile (say M4A):
var transcoder = new MediaTranscoder();
var result = await transcoder.PrepareMediaStreamSourceTranscodeAsync(
source,
destination,
MediaEncodingProfile.CreateM4a(AudioEncodingQuality.Medium)
);
await result.TranscodeAsync();
For more details, see the full code sample here.