         }
     }
     
+    //MARK: camera
     private func setupCamera()
     {
         guard let cameraView = RPScreenRecorder.shared().cameraPreviewView else {return}
         if cameraView.constraints.count > 0 {return}
         
-        let tap = UITapGestureRecognizer(target: self, action: #selector(switchCamera(_:)))
-        tap.numberOfTapsRequired = 1
+        let tap = UITouchGestureRecognizer(target: self, action: #selector(switchCamera(_:)))
         cameraView.addGestureRecognizer(tap)
-    }
-    
-    @objc private func switchCamera(_ gesture:UITapGestureRecognizer)
-    {
-        if gesture.state == .recognized
+        
+        let pan = UIPanGestureRecognizer(target: self, action: #selector(moveCameraPreview(_:)))
+        pan.maximumNumberOfTouches = 1
+        cameraView.addGestureRecognizer(pan)
+        tap.require(toFail: pan)
+    }
+    
+    @objc private func moveCameraPreview(_ gesture:UIPanGestureRecognizer)
+    {
+        guard let view = gesture.view else {return}
+        switch gesture.state
+        {
+            case .began:
+                gesture.setTranslation(CGPoint.zero, in: view)
+            case .changed:
+                let translation = gesture.translation(in: view)
+                view.frame = view.frame.offsetBy(dx: translation.x, dy: translation.y)
+                gesture.setTranslation(CGPoint.zero, in: view)
+            default:break
+        }
+    }
+    
+    @objc private func switchCamera(_ gesture:UITouchGestureRecognizer)
+    {
+        guard gesture.state == .began else { return }
+        if gesture.numberOfTouches >= 2
         {
             let position = RPScreenRecorder.shared().cameraPosition
             switch position
             {
-                case .back:
-                    RPScreenRecorder.shared().cameraPosition = .front
-                case .front:
-                    RPScreenRecorder.shared().cameraPosition = .back
+                case .back: RPScreenRecorder.shared().cameraPosition = .front
+                case .front: RPScreenRecorder.shared().cameraPosition = .back
+            }
+        }
+        else
+        {
+            if let view = RPScreenRecorder.shared().cameraPreviewView
+            {
+                let alpha:CGFloat
+                if view.alpha == 1.0
+                {
+                    alpha = 0.2
+                }
+                else
+                {
+                    alpha = 1.0
+                }
+                
+                view.layer.removeAllAnimations()
+                UIView.animate(withDuration: 0.2)
+                {
+                    view.alpha = alpha
+                }
             }
         }
     }

            case .audioMic:return "audio_mic"
            case .video:return "video"
        }
    }
}


            }
        }
        
        timeOffset = CMSampleBufferGetPresentationTimeStamp(sample)
        
        writer.startWriting()
        writer.startSession(atSourceTime: timeOffset)
    }
    
    private(set) var timeOffset:CMTime = kCMTimeZero
    
    private let background = DispatchQueue(label: "video_encode_queue")
    func append(sample:CMSampleBuffer, type:RPSampleBufferType)
    {
