Swift 3录制视频 - mp4文件中缺少音频

时间:2017-07-11 19:58:00

标签: ios swift3 avfoundation

此代码生成一个缺少音频的本地mp4文件。 如果我在quicktime播放器检查器中查看此文件,它具有H264格式但没有AAC音频。 如果我在应用程序中播放文件,则没有声音。

最奇怪的是,我可以将同一个文件作为多部分文档上传到服务器,并且没问题。我可以从服务器下载文件,它有AAC音频数据。

class VideoViewController: UIViewController, AVCaptureFileOutputRecordingDelegate
{
    var captureDevice : AVCaptureDevice! // check capture device availability
    var videoInput:AVCaptureDeviceInput?
    let captureSession = AVCaptureSession() // to create capture session
    var previewLayer : AVCaptureVideoPreviewLayer? // to add video inside container
    var videoFileOutput:AVCaptureMovieFileOutput!
    var audioDevice:AVCaptureDevice?
    var audioInput:AVCaptureDeviceInput?

    var playerController = AVPlayerViewController()

    @IBOutlet weak var videoView: UIView!

    override func viewDidLoad()
    {
        super.viewDidLoad()
    }

    override func viewDidDisappear(_ animated: Bool)
    {
        shutDown()
    }

    func isVideoSetup() -> Bool
    {
        if(captureDevice == nil)
        {
            return false
        }

        return true
    }

    func setupCamera()
    {

        print("setupCamera")

        audioDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)
        print("Audio capture device found")

        //Do any additional setup after loading the view, typically from a nib.
        // you have 3 option High quality recording, Medium quality recording and Low quality recording
        captureSession.sessionPreset = AVCaptureSessionPresetLow

        let deviceDescoverySession = AVCaptureDeviceDiscoverySession.init(deviceTypes: [AVCaptureDeviceType.builtInWideAngleCamera], mediaType: AVMediaTypeVideo, position: AVCaptureDevicePosition.front)

        if(deviceDescoverySession != nil)
        {
            for device in deviceDescoverySession!.devices
            {
                if device.position == AVCaptureDevicePosition.front
                {
                    print("Video capture device found")
                    captureDevice = device
                    setupCamera2()
                    return
                }
            }
        }

        print("Capture device not found")
        fatalError(errorMsg:"Camera was not found.")

    }

    //Configuring & Initializing the camera
    func setupCamera2()
    {
        print("setupCamera2")

        do {
            audioInput = try AVCaptureDeviceInput(device: audioDevice)
            print("audio input created")

        } catch {
            print("Unable to add audio device to the recording.")
            fatalError(errorMsg:"Unable to access audio device.")
            return
        }



        if let device = captureDevice {
            do{
                try device.lockForConfiguration()

            }catch{
                print("error")
            }
        }

        let err : NSError? = nil

        do{
            videoInput = try AVCaptureDeviceInput(device: captureDevice)
            captureSession.addInput(videoInput)
        }catch
        {
            print("error")
            fatalError(errorMsg:"Unknown error.")
            return
        }

        if err != nil
        {
            print("error: \(String(describing: err?.localizedDescription))")
            fatalError(errorMsg:String(describing: err?.localizedDescription))
            return
        }

        self.captureSession.addInput(audioInput)
        print("added audio device")

        previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
        // thumbnail is a ui container, your camera shows inside this container
        previewLayer?.frame = videoView.layer.bounds
        previewLayer?.connection.videoOrientation = AVCaptureVideoOrientation.portrait
        previewLayer?.videoGravity = AVLayerVideoGravityResizeAspect
        videoView.layer.addSublayer(previewLayer!)
        captureSession.startRunning()
        captureDevice?.unlockForConfiguration()
    }



    func startRecording()
    {
        if(captureSession.outputs.count > 0)
        //if(captureSession.canAddOutput(videoFileOutput))
        {
            print("Resetting inputs")
            captureSession.removeInput(audioInput)
            captureSession.removeInput(videoInput)
            captureSession.removeOutput(videoFileOutput)
            setupCamera2()
        }

        videoFileOutput = AVCaptureMovieFileOutput()
        videoFileOutput.movieFragmentInterval = CMTime(seconds: 1, preferredTimescale: 30)

        captureSession.addOutput(videoFileOutput)

        do
        {
            try FileManager.default.removeItem(at: dataMgr.videoFileURL)
        }
        catch
        {
        }

        let recordingDelegate:AVCaptureFileOutputRecordingDelegate? = self
        videoFileOutput.startRecording(toOutputFileURL: dataMgr.videoFileURL, recordingDelegate: recordingDelegate)
    }

    func stopRecording()
    {
        //To end recording just call this function
        videoFileOutput.stopRecording()

    }


    func shutDown()
    {
        if(captureSession.outputs.count > 0)
        {
            captureSession.removeInput(audioInput)
            captureSession.removeInput(videoInput)
            captureSession.removeOutput(videoFileOutput)
        }

        captureSession.stopRunning()
    }


    func playVideo()
    {
        let item = AVPlayerItem(url: dataMgr.videoFileURL)
        let player = AVPlayer(playerItem: item)
        playerController = AVPlayerViewController()
        playerController.player = player
        playerController.view.frame = CGRect(x:videoView.frame.origin.x, y:videoView.frame.origin.y, width: videoView.frame.width, height: videoView.frame.height)
        self.addChildViewController(playerController)
        videoView.addSubview(playerController.view)
    }

    func stopPlaying()
    {
        //playerController.view.removeSubviews()
        playerController.removeFromParentViewController()
        videoView.removeSubviews()
        utils.removeAllSubviews(vw: videoView)
    }


    @available(iOS 4.0, *)
    public func capture(_ captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAt outputFileURL: URL!, fromConnections connections: [Any]!, error: Error!)
    {
        print("capture did finish")
        print(captureOutput);
        print(outputFileURL);
        print("size of file=" + String(utils.getFileSize(fileURL: outputFileURL)))
    }

    func fatalError(errorMsg:String)
    {
        let alert = UIAlertController(title: "Error", message: errorMsg, preferredStyle: UIAlertControllerStyle.alert)    
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { action in
            app.switchScreens(newscreen:"StartViewController")

        }))
        self.present(alert, animated: true, completion: nil)

    }
}

1 个答案:

答案 0 :(得分:1)

这很疯狂,但我通过更改我保存的文件名来解决这个问题

function Rice(){
if(document.getElementById("Rice").style.display == "none"){
document.getElementById("Rice").style.display = "block";
}else{
document.getElementById("Rice").style.display = "none";
}
}

function boiledRice(){
if(document.getElementById("boiledRice").style.display == "none"){
document.getElementById("boiledRice").style.display = "block";
}else{
document.getElementById("boiledRice").style.display = "none";
}
}

function friedRice(){
if(document.getElementById("friedRice").style.display == "none"){
document.getElementById("friedRice").style.display = "block";
}else{
document.getElementById("friedRice").style.display = "none";
}
}

 <div class="media-right">
                        <table class="table">
                            <tr>
                                <td>
                                    <a onclick="Rice()"><h3 class="menu-title">Rice</h3></a><div id="Rice" style="display:none;"><ul><li>1</li><li>2</li><li>3</li></ul></div></td> <!--make this tr expandable and collapsable-->
                                <td>
                                    <div class="menu-rate">&#36;100.00</div>
                                </td>
                            </tr>

                             <tr>
                                <td>
                                    <a onclick="friedRice()"><h3 class="menu-title">Fried Rice</h3></a><div id="friedRice" style="display:none;"><ul><li>1</li><li>2</li><li>3</li></ul></div></td>
                                <td>
                                    <div class="menu-rate">&#36;50.00</div>
                                </td>
                            </tr>
                            <tr>
                                <td>
                                    <a onclick="boiledRice()"><h3 class="menu-title">Boiled Rice</h3></a><div id="boiledRice" style="display:none;"><ul><li>1</li><li>2</li><li>3</li></ul></div></td>
                                <td>
                                    <div class="menu-rate">&#36;25.00</div>
                                </td>
                            </tr>
                         </table>

                    </div>