         }
         
         let mediaType = CMFormatDescriptionGetMediaType(fd)
+        let pts = sampleBuffer.presentationTimeStamp
+        
+        // discard sample timestamped eariler than last appended
+        let lastPTS = (mediaType == kCMMediaType_Video
+                        ? lastVideoPTS
+                        : (mediaType == kCMMediaType_Audio ? lastAudioPTS : nil))
+        if lastPTS != nil && lastPTS!.seconds > pts.seconds {
+            return
+        }
         
         if CMSampleBufferDataIsReady(sampleBuffer) {
             if writer.status == .unknown {
                 if writer.startWriting() {
-                    let startTime = sampleBuffer.presentationTimeStamp
+                    let startTime = pts
                     writer.startSession(atSourceTime: startTime)
                     //logger.d(String(format:"WRITER Start session at pts:%2.2f", startTime.seconds))
                 } else {


    
    public func append(sbuf sampleBuffer: CMSampleBuffer) {
        guard let writer = self.writer else {
            print("writer not initialized")
            return

    public let statusInfo:[InfoKey: Any]
    
    fileprivate var firstAudioSampleHandled: Bool = false
    fileprivate var finishing = false
    fileprivate var lastAudioPTS: CMTime?
    fileprivate var lastVideoPTS: CMTime?
    
    static func writerInputVideo(settings: AVCWriterVideoSettings?) -> AVAssetWriterInput? {
        guard let settings = settings else {
