同时录制音频和播放声音 - C# - Windows Phone 8.1
问题描述:
我正在尝试录制音频并直接播放它(我想在耳机中听到我的声音而不保存它),但是MediaElement和MediaCapture似乎不是同时工作。 我初始化我MediaCapture这样:同时录制音频和播放声音 - C# - Windows Phone 8.1
_mediaCaptureManager = new MediaCapture();
var settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
settings.MediaCategory = MediaCategory.Other;
settings.AudioProcessing = AudioProcessing.Default;
await _mediaCaptureManager.InitializeAsync(settings);
但是我真的不知道如何着手;我wonderign如果这些方法之一可以工作(我tryied实现它们没有成功,我还没有发现的例子):
- 是否有使用StartPreviewAsync()录制音频,办法或它仅适用于视频?我注意到,我得到以下错误:“指定的对象或值不存在”,而设置我的CaptureElement来源;它只发生,如果我写“settings.StreamingCaptureMode = StreamingCaptureMode.Audio;”而每一个作品的视频。
- 如何使用StartRecordToStreamAsync()记录流;我的意思是,我如何初始化IRandomAccessStream并从中读取?我是否可以在上写而我保持为呢?
-
我读到将MediaElement的AudioCathegory和MediaCapture的MediaCathegory更改为Communication可能有效。但是,虽然我的代码与以前的设置一起工作(它只需记录并保存在文件中),但如果我编写“settings.MediaCategory = MediaCategory.Communication;”,则不起作用。而不是“settings.MediaCategory = MediaCategory.Other;”。你能告诉我为什么吗? 这是我目前的计划,只是记录,保存和播放:
private async void CaptureAudio() { try { _recordStorageFile = await KnownFolders.VideosLibrary.CreateFileAsync(fileName, CreationCollisionOption.GenerateUniqueName); MediaEncodingProfile recordProfile = MediaEncodingProfile.CreateWav(AudioEncodingQuality.Auto); await _mediaCaptureManager.StartRecordToStorageFileAsync(recordProfile, this._recordStorageFile); _recording = true; } catch (Exception e) { Debug.WriteLine("Failed to capture audio:"+e.Message); } } private async void StopCapture() { if (_recording) { await _mediaCaptureManager.StopRecordAsync(); _recording = false; } } private async void PlayRecordedCapture() { if (!_recording) { var stream = await _recordStorageFile.OpenAsync(FileAccessMode.Read); playbackElement1.AutoPlay = true; playbackElement1.SetSource(stream, _recordStorageFile.FileType); playbackElement1.Play(); } }
如果您有任何建议,我会gratefull。 祝您有美好的一天。
答
您会考虑将目标锁定为Windows 10吗?新的AudioGraph API可以让你做到这一点,并且Scenario 2 (Device Capture) in the SDK sample很好地演示了它。
首先,将样品填充所有输出设备到一个列表:
private async Task PopulateDeviceList()
{
outputDevicesListBox.Items.Clear();
outputDevices = await DeviceInformation.FindAllAsync(MediaDevice.GetAudioRenderSelector());
outputDevicesListBox.Items.Add("-- Pick output device --");
foreach (var device in outputDevices)
{
outputDevicesListBox.Items.Add(device.Name);
}
}
然后获取打造AudioGraph:
AudioGraphSettings settings = new AudioGraphSettings(AudioRenderCategory.Media);
settings.QuantumSizeSelectionMode = QuantumSizeSelectionMode.LowestLatency;
// Use the selected device from the outputDevicesListBox to preview the recording
settings.PrimaryRenderDevice = outputDevices[outputDevicesListBox.SelectedIndex - 1];
CreateAudioGraphResult result = await AudioGraph.CreateAsync(settings);
if (result.Status != AudioGraphCreationStatus.Success)
{
// TODO: Cannot create graph, propagate error message
return;
}
AudioGraph graph = result.Graph;
// Create a device output node
CreateAudioDeviceOutputNodeResult deviceOutputNodeResult = await graph.CreateDeviceOutputNodeAsync();
if (deviceOutputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// TODO: Cannot create device output node, propagate error message
return;
}
deviceOutputNode = deviceOutputNodeResult.DeviceOutputNode;
// Create a device input node using the default audio input device
CreateAudioDeviceInputNodeResult deviceInputNodeResult = await graph.CreateDeviceInputNodeAsync(MediaCategory.Other);
if (deviceInputNodeResult.Status != AudioDeviceNodeCreationStatus.Success)
{
// TODO: Cannot create device input node, propagate error message
return;
}
deviceInputNode = deviceInputNodeResult.DeviceInputNode;
// Because we are using lowest latency setting, we need to handle device disconnection errors
graph.UnrecoverableErrorOccurred += Graph_UnrecoverableErrorOccurred;
// Start setting up the output file
FileSavePicker saveFilePicker = new FileSavePicker();
saveFilePicker.FileTypeChoices.Add("Pulse Code Modulation", new List<string>() { ".wav" });
saveFilePicker.FileTypeChoices.Add("Windows Media Audio", new List<string>() { ".wma" });
saveFilePicker.FileTypeChoices.Add("MPEG Audio Layer-3", new List<string>() { ".mp3" });
saveFilePicker.SuggestedFileName = "New Audio Track";
StorageFile file = await saveFilePicker.PickSaveFileAsync();
// File can be null if cancel is hit in the file picker
if (file == null)
{
return;
}
MediaEncodingProfile fileProfile = CreateMediaEncodingProfile(file);
// Operate node at the graph format, but save file at the specified format
CreateAudioFileOutputNodeResult fileOutputNodeResult = await graph.CreateFileOutputNodeAsync(file, fileProfile);
if (fileOutputNodeResult.Status != AudioFileNodeCreationStatus.Success)
{
// TODO: FileOutputNode creation failed, propagate error message
return;
}
fileOutputNode = fileOutputNodeResult.FileOutputNode;
// Connect the input node to both output nodes
deviceInputNode.AddOutgoingConnection(fileOutputNode);
deviceInputNode.AddOutgoingConnection(deviceOutputNode);
一旦所有做到这一点,你可以录制文件,同时播放录制的音频,如下所示:
private async Task ToggleRecordStop()
{
if (recordStopButton.Content.Equals("Record"))
{
graph.Start();
recordStopButton.Content = "Stop";
}
else if (recordStopButton.Content.Equals("Stop"))
{
// Good idea to stop the graph to avoid data loss
graph.Stop();
TranscodeFailureReason finalizeResult = await fileOutputNode.FinalizeAsync();
if (finalizeResult != TranscodeFailureReason.None)
{
// TODO: Finalization of file failed. Check result code to see why, propagate error message
return;
}
recordStopButton.Content = "Record";
}
}
谢谢你的帮助。因此,自从我编写Windows Phone应用程序以来,我不得不等待Windows 10 Mobile的发布,不是吗?我需要构建AudioGraph等的这些类将通过更新添加到Visual Studio中,否则我必须下载某些内容?对不起,但我对Visual Studio还没有信心... –
您必须升级到Visual Studio 2015才能开发Windows 10(这是免费的社区版)。您还可以加入Windows Insiders计划,将您的手机升级到Windows 10并开始开发并取得领先。 – Mike
太好了,我安装了Visual Studio 2015,现在我有了需要了解这些示例的命名空间。但现在我有另一个问题:我怎样才能下载你发给我的项目(https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/AudioCreation)?我无法真正找到下载zip文件的方法(页面不显示任何按钮).. –