     
     func save(completion:(()->Void)? = nil)
     {
-//        Timer.scheduledTimer(withTimeInterval: 1/10, repeats: true)
-//        { (timer) in
-//
-//            var num = 0
-//            for (_, track) in self.movieTracks
-//            {
-//                if track.isReadyForMoreMediaData { num += 1 }
-//            }
-//
-//            if num == self.movieTracks.count
-//            {
-//                self.writer.finishWriting
-//                {
-//                    print("finish", self.writer.status, self.writer.error ?? "success")
-//                    completion?()
-//                }
-//            }
-//        }
-        
         self.writer.finishWriting
         {
             print("finish", self.writer.status, self.writer.error ?? "success")

    }
    
    var lastime:CMTime = kCMTimeZero
    
    private let queueAudio = DispatchQueue(label: "audio_encode_queue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
    private let queueVideo = DispatchQueue(label: "video_encode_queue", qos: .background, attributes: .concurrent, autoreleaseFrequency: .inherit, target: nil)
    func append(sample:CMSampleBuffer, type:RPSampleBufferType)
    {
        if !initialized
        {
            setup(sample: sample)
        }
        
        guard CMSampleBufferIsValid(sample) else
        {
            print(sample)
            return
        }
        
        if let track = movieTracks[type], track.isReadyForMoreMediaData
        {
            if type == .video
            {
                let position = CMSampleBufferGetPresentationTimeStamp(sample)
                print(position.seconds, (position - lastime).seconds)
                lastime = position
                queueVideo.async
                {
                    track.append(sample)
                    if self.writer.status == .failed
                    {
                        print(self.writer.error!)
                    }
                }
            }
            else
            {
                queueAudio.async
                {
                    track.append(sample)
                    if self.writer.status == .failed
                    {
                        print(self.writer.error!)
                    }
                }
            }

    var fetchUnityTime:(()->Double)? // get game timestamp for timesync
    private func synchronize(timestamp value:Double)
    {
        print("sychronize", value)
        if let time = fetchUnityTime?()
        {
            syncdata.append([value, time])
