同时录制音频和播放声音 - C# - Windows Phone 8.1
Recording Audio and Playing sound at the same time - C# - Windows Phone 8.1
我正在尝试录制音频并直接播放(我想在耳机中听到我的声音而不保存它)但是 MediaElement 和 MediaCapture 似乎无法同时工作。
我这样初始化我的 MediaCapture:
_mediaCaptureManager = new MediaCapture();
var settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
settings.MediaCategory = MediaCategory.Other;
settings.AudioProcessing = AudioProcessing.Default;
await _mediaCaptureManager.InitializeAsync(settings);
但是我真的不知道如何进行;我想知道这些方法中的一种是否可行(我尝试实施它们但没有成功,而且我还没有找到示例):
- 有没有办法使用 StartPreviewAsync() 录制音频,或者它只适用于视频?我注意到在设置我的 CaptureElement 源时出现以下错误:"The specified object or value does not exist";只有当我写 "settings.StreamingCaptureMode = StreamingCaptureMode.Audio;" 而 everyting 为 .Video.
工作时才会发生
- 如何使用 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();
}
}
如果您有任何建议,我将不胜感激。
祝你有个美好的一天。
您会考虑改为定位 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";
}
}
我正在尝试录制音频并直接播放(我想在耳机中听到我的声音而不保存它)但是 MediaElement 和 MediaCapture 似乎无法同时工作。 我这样初始化我的 MediaCapture:
_mediaCaptureManager = new MediaCapture();
var settings = new MediaCaptureInitializationSettings();
settings.StreamingCaptureMode = StreamingCaptureMode.Audio;
settings.MediaCategory = MediaCategory.Other;
settings.AudioProcessing = AudioProcessing.Default;
await _mediaCaptureManager.InitializeAsync(settings);
但是我真的不知道如何进行;我想知道这些方法中的一种是否可行(我尝试实施它们但没有成功,而且我还没有找到示例):
- 有没有办法使用 StartPreviewAsync() 录制音频,或者它只适用于视频?我注意到在设置我的 CaptureElement 源时出现以下错误:"The specified object or value does not exist";只有当我写 "settings.StreamingCaptureMode = StreamingCaptureMode.Audio;" 而 everyting 为 .Video. 工作时才会发生
- 如何使用 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(); } }
如果您有任何建议,我将不胜感激。 祝你有个美好的一天。
您会考虑改为定位 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";
}
}