【问题标题】:Recording Audio and Playing sound at the same time - C# - Windows Phone 8.1同时录制音频和播放声音 - C# - Windows Phone 8.1
【发布时间】:2015-09-06 20:31:05
【问题描述】:

我正在尝试录制音频并直接播放(我想在耳机中听到我的声音而不保存它)但是 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);

但是我真的不知道如何进行;我想知道其中一种方法是否可行(我尝试实施它们但没有成功,我还没有找到示例):

  1. 有没有办法使用 StartPreviewAsync() 录制音频,或者它只适用于视频?我注意到在设置 CaptureElement Source 时出现以下错误:“指定的对象或值不存在”;只有当我写“settings.StreamingCaptureMode = StreamingCaptureMode.Audio;”时才会发生虽然一切都适用于 .Video。
  2. 如何使用 StartRecordToStreamAsync() 录制到流中;我的意思是,我该如何初始化 IRandomAccessStream 并从中读取?我可以流,同时继续吗?
  3. 我读到将 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();
       }
    }
    

如果您有任何建议,我将不胜感激。 祝你有美好的一天。

【问题讨论】:

    标签: c# windows-phone-8.1 windows-applications


    【解决方案1】:

    您会考虑改为以 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 并继续开发并抢占先机。
    • 太好了,我安装了 Visual Studio 2015,现在我有了理解这些示例所需的命名空间。但是现在我还有一个问题:我如何下载你发给我的那个项目(github.com/Microsoft/Windows-universal-samples/tree/master/…)?我真的找不到下载 zip 文件的方法(页面没有显示任何按钮)..
    • 如果您转到存储库的根目录(此处为:github.com/Microsoft/Windows-universal-samples),右侧有一个“下载 ZIP”按钮。但是你应该多了解一下 github,它提供了你可能喜欢的功能。
    • 这个项目真的适合任何人吗?当我运行它时,我会通过我的扬声器获得反馈,它会保存一个包含数据的文件,但它不会播放任何内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多