【问题标题】:How to record video and play audio at the same time (swift tutorial)如何同时录制视频和播放音频(快速教程)
【发布时间】:2016-04-23 19:24:51
【问题描述】:

所以您想录制视频播放用户库中的音乐同时?不要再看了。以下是答案。

【问题讨论】:

    标签: ios swift avfoundation avaudioplayer mpmusicplayercontroller


    【解决方案1】:

    对于音频播放,您将使用AVAudioPlayer。您所要做的就是将AVAudioPlayer 声明为全局变量(我将其命名为audioPlayer)并实现以下代码。

    在用户选择他/她想要播放的歌曲之后使用它:

    func mediaPicker(mediaPicker: MPMediaPickerController, didPickMediaItems mediaItemCollection: MPMediaItemCollection) {
        let pickerItem: MPMediaItem = mediaItemCollection.items[0]
        let songURL = pickerItem.valueForProperty(MPMediaItemPropertyAssetURL)
        if let sURL = songURL as? NSURL
        {
            songTitle = pickerItem.title!
            do
            {
                audioPlayer = try AVAudioPlayer(contentsOfURL: sURL)
            }
            catch
            {
                print("Can't Create Audio Player: \(error)")
            }
        }
        dismissViewControllerAnimated(true, completion: { () -> Void in
            audioPlayer.play()
        })
    }
    

    您还需要设置音频会话viewDidLoad)。如果您希望在录制时播放音频,这一点至关重要:

     // Audio Session Setup
        do
        {
            try audioSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
        }
        catch
        {
            print("Can't Set Audio Session Category: \(error)")
        }
        AVAudioSessionCategoryOptions.MixWithOthers
        do
        {
            try audioSession.setMode(AVAudioSessionModeVideoRecording)
        }
        catch
        {
            print("Can't Set Audio Session Mode: \(error)")
        }
        // Start Session
        do
        {
            try audioSession.setActive(true)
        }
        catch
        {
            print("Can't Start Audio Session: \(error)")
        }
    

    现在开始视频录制。您将使用AVCaptureSession。将以下内容声明为全局变量:

    let captureSession = AVCaptureSession()
    var currentDevice: AVCaptureDevice?
    var videoFileOutput: AVCaptureMovieFileOutput?
    var cameraPreviewLayer: AVCaptureVideoPreviewLayer?
    

    然后在viewDidLoad 中配置会话。注意:视频预览在容器中,整个视频相关代码在不同的视图控制器中,但使用视图而不是容器应该可以正常工作:

    // Preset For 720p
    captureSession.sessionPreset = AVCaptureSessionPreset1280x720
    
    // Get Available Devices Capable Of Recording Video
    let devices = AVCaptureDevice.devicesWithMediaType(AVMediaTypeVideo) as! [AVCaptureDevice]
    
    // Get Back Camera
    for device in devices
    {
        if device.position == AVCaptureDevicePosition.Back
        {
            currentDevice = device
        }
    }
    let camera = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo)
    
    // Audio Input
    let audioInputDevice = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio)
    
    do
    {
        let audioInput = try AVCaptureDeviceInput(device: audioInputDevice)
    
        // Add Audio Input
        if captureSession.canAddInput(audioInput)
        {
            captureSession.addInput(audioInput)
        }
        else
        {
            NSLog("Can't Add Audio Input")
        }
    }
    catch let error
    {
        NSLog("Error Getting Input Device: \(error)")
    }
    
    // Video Input
    let videoInput: AVCaptureDeviceInput
    do
    {
        videoInput = try AVCaptureDeviceInput(device: camera)
    
        // Add Video Input
        if captureSession.canAddInput(videoInput)
        {
            captureSession.addInput(videoInput)
        }
        else
        {
            NSLog("ERROR: Can't add video input")
        }
    }
    catch let error
    {
        NSLog("ERROR: Getting input device: \(error)")
    }
    
    // Video Output
    videoFileOutput = AVCaptureMovieFileOutput()
    captureSession.addOutput(videoFileOutput)
    
    // Show Camera Preview
    cameraPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
    view.layer.addSublayer(cameraPreviewLayer!)
    cameraPreviewLayer?.videoGravity = AVLayerVideoGravityResizeAspectFill
    let width = view.bounds.width
    cameraPreviewLayer?.frame = CGRectMake(0, 0, width, width)
    
    // Bring Record Button To Front & Start Session
    view.bringSubviewToFront(recordButton)
    captureSession.startRunning()
    print(captureSession.inputs)
    

    然后你创建一个@IBAction 来处理用户按下记录按钮时的处理(我只是使用了一个简单的按钮,我把它做成了红色和圆形):

    @IBAction func capture(sender: AnyObject) {
        do
        {
            initialOutputURL = try NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: true).URLByAppendingPathComponent("output").URLByAppendingPathExtension("mov")
        }
        catch
        {
            print(error)
        }
        if !isRecording
        {
            isRecording = true
    
            UIView.animateWithDuration(0.5, delay: 0.0, options: [.Repeat, .Autoreverse, .AllowUserInteraction], animations: { () -> Void in
                self.recordButton.transform = CGAffineTransformMakeScale(0.75, 0.75)
                }, completion: nil)
    
            videoFileOutput?.startRecordingToOutputFileURL(initialOutputURL, recordingDelegate: self)
        }
        else
        {
            isRecording = false
    
            UIView.animateWithDuration(0.5, delay: 0, options: [], animations: { () -> Void in
                self.recordButton.transform = CGAffineTransformMakeScale(1.0, 1.0)
                }, completion: nil)
            recordButton.layer.removeAllAnimations()
            videoFileOutput?.stopRecording()
        }
    }
    

    那么剩下要做的就是将视频保存到(大概)相机胶卷。但我不会包括在内。你必须自己付出一些努力。 (提示:UISaveVideoAtPathToSavedPhotosAlbum

    这就是伙计们。这就是您如何使用AVFoundation 同时录制视频和播放库中的音乐。

    【讨论】:

    • Lawrence413,非常感谢,这非常有帮助!!我有一个问题......是否可以停止麦克风录音。我只想要文件中带有音频的视频。这是在各种应用程序中完成的,包括 TikTok、Instagram 等。我已经尝试了很多事情,但无法弄清楚。任何帮助表示赞赏!
    • 我不确定,但我认为你不能。这可能是系统音频,我认为开发人员无法访问它。我相信 Instagram 的工作方式是将视频与歌曲合并,但您无法录制。我不知道TikTok。即使是 Apple 的屏幕录制应用程序也不会录制系统音频,因此它应该是一个可靠的指标,表明您无法做到。
    • 实际上它确实录制了系统音频!这是可能的!
    • @LilMoke 嗨,您是否能够弄清楚,或者您是否找到任何链接来解释如何停止麦克风但将音频和视频放在一起?
    【解决方案2】:

    一旦你像下面这样设置了 AVAudioSession,它就可以正常工作了。

    try? AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playAndRecord, mode: AVAudioSession.Mode.videoRecording, options: AVAudioSession.CategoryOptions.mixWithOthers)

    【讨论】:

    • 任何其他提示。如果我一个接一个地播放正在录制的两个文件,我会在几秒钟的录音中得到音频,录音文件最终没有音频。请帮帮我
    猜你喜欢
    • 2017-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-12
    • 2012-04-09
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多