6

我用 录制视频AVAssetWriter。用户可以发送视频,然后我打电话finishWriting,或者取消录制,然后我打电话cancelWriting

我如何记录:

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!){
        guard !message_to_send else{
            return
        }
        guard is_recording else{
            return
        }
        guard CMSampleBufferDataIsReady(sampleBuffer) else{
            print("data not ready")
            return
        }
        guard let w=file_writer else{
            print("video writer nil")
            return
        }
        guard let sb=sampleBuffer else{
            return
        }

        if w.status == .unknown /*&& start_recording_time==nil*/{
            if captureOutput==video_output{
                print("\nSTART RECORDING")
                w.startWriting()
                start_recording_time=CMSampleBufferGetPresentationTimeStamp(sb)
                w.startSession(atSourceTime: start_recording_time!)
            }else{
                return
            }
        }

        if w.status == .failed{
            print("failed with error:", w.error ?? "")
            stop_record()
            return
        }

        guard w.status == .writing else{
            print("not writing")
            return
        }

        if captureOutput==audio_output{
            if audio_writer.isReadyForMoreMediaData && video_written{
                audio_writer.append(sb)
            }else{
                print("audio writer not ready OR video not written yet")
            }
        }else if captureOutput==video_output{
            if video_writer.isReadyForMoreMediaData /*&& is_recording*/{
                video_writer.append(sb)   // << this line gets called after stop_record is called and causes a crash
                if !video_written{
                    print("added 1st video frame")
                    video_written=true
                }
                //print("write video")
            }else{
                print("video writer not ready")
            }
        }
    }
}

我如何停止录制:

func stop_record(){
        print("\nstop_record")
        guard is_recording else{
            print("not recording > return")
            return
        }

        is_recording=false
        cam_q.async{
            self.is_recording=false
        }

        print("file writer status", file_writer.status.rawValue)
        if file_writer.status.rawValue==1{
            self.video_writer?.markAsFinished()
            print("video finished")
            self.audio_writer?.markAsFinished()
            print("audio finished")
        }else{
            print("not writing")
        }

        if !self.message_to_send{
            print("cancel writing")
            self.file_writer.cancelWriting()
            return
        }

        file_writer.finishWriting(){
            print("finished writing")
            DispatchQueue.main.async{
                let st=self.file_writer.status
                if st == .failed{
                    print("status: failed")
                }else if st == .completed{
                    print("status: completed")
                }else if st == .cancelled{
                    print("status: cancelled")
                }else{
                    print("status: unknown")
                }

                if let e=self.file_writer.error{
                    print("stop record error:", e)
                }

                if self.message_to_send{
                    send_message()
                }
            }
        }
    }

当我打电话时stop_record,有时它会崩溃。即使file_writer应该停止写作并且如果我在 中进行了多次验证,也会didOutputSampleBuffer调用此行:

video_writer.append(sb)

我得到:

停止记录

文件写入器状态 1

视频完成

音频完成

libc++abi.dylib:以 NSException 类型的未捕获异常终止

我在没有调用的情况下尝试了相同的代码,markAsFinished但它也崩溃了(我更经常说)。

我想知道这是否是线程问题(因为stop_recorddidOutputSampleBuffer方法没有在同一个线程上调用)。无论如何,我不知道我做错了什么。如果有人可以帮助我,我将不胜感激。

4

0 回答 0