|  | @@ -130,7 +130,10 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |  //    public  var seekQueue: DispatchQueue!
 |  |  //    public  var seekQueue: DispatchQueue!
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      // 是否为导出模式
 |  |      // 是否为导出模式
 | 
											
												
													
														|  | -    public   var mIsExport: Bool = false
 |  | 
 | 
											
												
													
														|  | 
 |  | +    public var mIsExport: Bool = false
 | 
											
												
													
														|  | 
 |  | +    
 | 
											
												
													
														|  | 
 |  | +    //是否使用AVPlayer播放音乐
 | 
											
												
													
														|  | 
 |  | +    public var isUsedAVPlayer:Bool = false
 | 
											
												
													
														|  |      
 |  |      
 | 
											
												
													
														|  |      //打印开始时间
 |  |      //打印开始时间
 | 
											
												
													
														|  |      var debugStartTime:CFTimeInterval?
 |  |      var debugStartTime:CFTimeInterval?
 | 
											
										
											
												
													
														|  | @@ -138,7 +141,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |       // 画布的大小 注意要是偶数 要不在 IOS 13上会有绿边 自动放大到偶数
 |  |       // 画布的大小 注意要是偶数 要不在 IOS 13上会有绿边 自动放大到偶数
 | 
											
												
													
														|  |      public var mShowVidoSize: CGSize = cVideoCannvasSizeOneToOne {
 |  |      public var mShowVidoSize: CGSize = cVideoCannvasSizeOneToOne {
 | 
											
												
													
														|  |          didSet {
 |  |          didSet {
 | 
											
												
													
														|  | -            BFLog(2, message: "mShowVidoSize is move input  \(mShowVidoSize)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "mShowVidoSize is move input  \(mShowVidoSize)")
 | 
											
												
													
														|  |              do {
 |  |              do {
 | 
											
												
													
														|  |                  displayLink?.isPaused = true
 |  |                  displayLink?.isPaused = true
 | 
											
												
													
														|  |                  imageFramebuffer = try Framebuffer(context: sharedImageProcessingContext, orientation: .portrait, size: GLSize(width: GLint(mShowVidoSize.width), height: GLint(mShowVidoSize.height)), textureOnly: true)
 |  |                  imageFramebuffer = try Framebuffer(context: sharedImageProcessingContext, orientation: .portrait, size: GLSize(width: GLint(mShowVidoSize.width), height: GLint(mShowVidoSize.height)), textureOnly: true)
 | 
											
										
											
												
													
														|  | @@ -152,7 +155,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |      // 初始化方法
 |  |      // 初始化方法
 | 
											
												
													
														|  |      public init(asset: AVAsset, videoComposition: AVVideoComposition?, audioMix: AVAudioMix?, playAtActualSpeed: Bool = false, loop: Bool = false, audioSettings: [String: Any]? = nil) throws {
 |  |      public init(asset: AVAsset, videoComposition: AVVideoComposition?, audioMix: AVAudioMix?, playAtActualSpeed: Bool = false, loop: Bool = false, audioSettings: [String: Any]? = nil) throws {
 | 
											
												
													
														|  |          self.asset = asset
 |  |          self.asset = asset
 | 
											
												
													
														|  | -        BFLog(2, message: "asset 资源的总时长\(asset.duration.seconds) \(asset.duration)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "asset 资源的总时长\(asset.duration.seconds) \(asset.duration)")
 | 
											
												
													
														|  |          self.audioMix = audioMix
 |  |          self.audioMix = audioMix
 | 
											
												
													
														|  |          self.audioSettings = audioSettings
 |  |          self.audioSettings = audioSettings
 | 
											
												
													
														|  |          self.videoComposition = videoComposition
 |  |          self.videoComposition = videoComposition
 | 
											
										
											
												
													
														|  | @@ -160,7 +163,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |          self.loop = loop
 |  |          self.loop = loop
 | 
											
												
													
														|  |          yuvConversionShader = crashOnShaderCompileFailure("MovieInput") { try sharedImageProcessingContext.programForVertexShader(defaultVertexShaderForInputs(2), fragmentShader: YUVConversionFullRangeFragmentShader) }
 |  |          yuvConversionShader = crashOnShaderCompileFailure("MovieInput") { try sharedImageProcessingContext.programForVertexShader(defaultVertexShaderForInputs(2), fragmentShader: YUVConversionFullRangeFragmentShader) }
 | 
											
												
													
														|  |          if asset.duration.seconds <= 0 {
 |  |          if asset.duration.seconds <= 0 {
 | 
											
												
													
														|  | -            BFLog(2, message: "asset 资源的总时长为0,返回")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "asset 资源的总时长为0,返回")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |    
 |  |    
 | 
											
										
											
												
													
														|  | @@ -170,10 +173,10 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          if #available(iOS 10, *){
 |  |          if #available(iOS 10, *){
 | 
											
												
													
														|  |              displayLink?.preferredFramesPerSecond = 30
 |  |              displayLink?.preferredFramesPerSecond = 30
 | 
											
												
													
														|  | -//            seekQueue = DispatchQueue(label: "PQ.MovieInput.seeking", qos: .userInteractive, attributes: .initiallyInactive, autoreleaseFrequency: .never, target: nil)
 |  | 
 | 
											
												
													
														|  | 
 |  | + 
 | 
											
												
													
														|  |          }else{
 |  |          }else{
 | 
											
												
													
														|  |              displayLink?.frameInterval = 2
 |  |              displayLink?.frameInterval = 2
 | 
											
												
													
														|  | -//            seekQueue = DispatchQueue(label: "PQ.MovieInput.seeking", qos: .userInteractive, attributes: [], autoreleaseFrequency: .inherit, target: nil)
 |  | 
 | 
											
												
													
														|  | 
 |  | + 
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          // 加入循环 要使用 common 不要让级别高的卡住回调事件
 |  |          // 加入循环 要使用 common 不要让级别高的卡住回调事件
 | 
											
												
													
														|  |          displayLink?.add(to: RunLoop.main, forMode: RunLoop.Mode.common)
 |  |          displayLink?.add(to: RunLoop.main, forMode: RunLoop.Mode.common)
 | 
											
										
											
												
													
														|  | @@ -197,7 +200,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |          self.audioInputStatusObserver?.invalidate()
 |  |          self.audioInputStatusObserver?.invalidate()
 | 
											
												
													
														|  |          self.avPlayerTimeObserver?.invalidate()
 |  |          self.avPlayerTimeObserver?.invalidate()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        BFLog(1, message: "movieinput release")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(1, message: "movieinput release")
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      // MARK: -
 |  |      // MARK: -
 | 
											
										
											
												
													
														|  | @@ -209,7 +212,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |          isPlay = false
 |  |          isPlay = false
 | 
											
												
													
														|  |          beginTime = 0
 |  |          beginTime = 0
 | 
											
												
													
														|  |          currentTime = .zero
 |  |          currentTime = .zero
 | 
											
												
													
														|  | -        BFLog(2, message: "初始化播放开始时间、\(CMTimeGetSeconds(timeRange.start)) 结束时间\(CMTimeGetSeconds(timeRange.end)) 播放总时长:\(CMTimeGetSeconds(timeRange.end) - CMTimeGetSeconds(timeRange.start))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "初始化播放开始时间、\(CMTimeGetSeconds(timeRange.start)) 结束时间\(CMTimeGetSeconds(timeRange.end)) 播放总时长:\(CMTimeGetSeconds(timeRange.end) - CMTimeGetSeconds(timeRange.start))")
 | 
											
												
													
														|  |    
 |  |    
 | 
											
												
													
														|  |          playeTimeRange = timeRange
 |  |          playeTimeRange = timeRange
 | 
											
												
													
														|  |          startTime = playeTimeRange.start
 |  |          startTime = playeTimeRange.start
 | 
											
										
											
												
													
														|  | @@ -219,7 +222,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      @objc func displayLinkClick(_ displayLink: CADisplayLink) {
 |  |      @objc func displayLinkClick(_ displayLink: CADisplayLink) {
 | 
											
												
													
														|  |          if assetReader == nil {
 |  |          if assetReader == nil {
 | 
											
												
													
														|  | -            BFLog(2, message: "self.assetReader is null !!!!!!!!!!")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "self.assetReader is null !!!!!!!!!!")
 | 
											
												
													
														|  |              displayLink.isPaused = true
 |  |              displayLink.isPaused = true
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
										
											
												
													
														|  | @@ -237,7 +240,14 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |              let duration = CMTimeGetSeconds(playeTimeRange.end)
 |  |              let duration = CMTimeGetSeconds(playeTimeRange.end)
 | 
											
												
													
														|  |              
 |  |              
 | 
											
												
													
														|  |              if !mIsExport {
 |  |              if !mIsExport {
 | 
											
												
													
														|  | -                self.currentTime = CMTimeMakeWithSeconds(CFAbsoluteTimeGetCurrent() - self.beginTime +  CMTimeGetSeconds(startTime ?? CMTime.zero), preferredTimescale: BASE_FILTER_TIMESCALE)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        
 | 
											
												
													
														|  | 
 |  | +               var midTime = CFAbsoluteTimeGetCurrent() - self.beginTime
 | 
											
												
													
														|  | 
 |  | +                if(midTime < 0.0001){
 | 
											
												
													
														|  | 
 |  | +                    midTime = 0
 | 
											
												
													
														|  | 
 |  | +                }
 | 
											
												
													
														|  | 
 |  | +                FilterLog(message: "CFAbsoluteTimeGetCurrent()\(CFAbsoluteTimeGetCurrent()) - self.beginTime  is:::::\(self.beginTime) 差值 \(midTime)")
 | 
											
												
													
														|  | 
 |  | +              
 | 
											
												
													
														|  | 
 |  | +                self.currentTime = CMTimeMakeWithSeconds(midTime +  CMTimeGetSeconds(startTime ?? CMTime.zero), preferredTimescale: BASE_FILTER_TIMESCALE)
 | 
											
												
													
														|  |              }else {
 |  |              }else {
 | 
											
												
													
														|  |                  self.currentTime = CMTimeMakeWithSeconds(self.beginTime +  CMTimeGetSeconds(startTime ?? CMTime.zero), preferredTimescale: BASE_FILTER_TIMESCALE)
 |  |                  self.currentTime = CMTimeMakeWithSeconds(self.beginTime +  CMTimeGetSeconds(startTime ?? CMTime.zero), preferredTimescale: BASE_FILTER_TIMESCALE)
 | 
											
												
													
														|  |                  self.beginTime = self.beginTime + 1 / 30
 |  |                  self.beginTime = self.beginTime + 1 / 30
 | 
											
										
											
												
													
														|  | @@ -247,12 +257,12 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |    
 |  |    
 | 
											
												
													
														|  |              let prgressValue = currTime / Float64(duration)
 |  |              let prgressValue = currTime / Float64(duration)
 | 
											
												
													
														|  |              
 |  |              
 | 
											
												
													
														|  | -            BFLog(2, message: "\(mIsExport) MovieOutput total frames appended:播放进行中 总用时: \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0)) 播放器开始时间:\(CMTimeGetSeconds(playeTimeRange.start)) 播放器原始结束时间:\(CMTimeGetSeconds(playeTimeRange.end))    总时间:\(CMTimeGetSeconds(playeTimeRange.end) - CMTimeGetSeconds(playeTimeRange.start)) 播放进度当前时间:\(currTime) 进度:\(prgressValue) 帧id \(totalFramesSent)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "\(mIsExport) MovieOutput total frames appended:播放进行中 总用时: \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0)) 播放器开始时间:\(CMTimeGetSeconds(playeTimeRange.start)) 播放器原始结束时间:\(CMTimeGetSeconds(playeTimeRange.end))    总时间:\(CMTimeGetSeconds(playeTimeRange.end) - CMTimeGetSeconds(playeTimeRange.start)) 播放进度当前时间:\(currTime) 进度:\(prgressValue) 帧id \(totalFramesSent)")
 | 
											
												
													
														|  |              totalFramesSent += 1
 |  |              totalFramesSent += 1
 | 
											
												
													
														|  |      
 |  |      
 | 
											
												
													
														|  | -            BFLog(2, message: "2222222222播放进行中 总用时: \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0)) 播放进度当前时间:\(currTime) 总时间为:\(duration)进度:\(prgressValue) 音频时长:\(    CMTimeGetSeconds(asset.duration) )")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "2222222222播放进行中 总用时: \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0)) 播放进度当前时间:\(currTime) 总时间为:\(duration)进度:\(prgressValue) 音频时长:\(    CMTimeGetSeconds(asset.duration) )")
 | 
											
												
													
														|  |              if currTime / duration > 1{
 |  |              if currTime / duration > 1{
 | 
											
												
													
														|  | -                BFLog(2, message: "全部播放完成 总用时为:\(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(2, message: "全部播放完成 总用时为:\(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0))")
 | 
											
												
													
														|  |                  if(self.completion != nil){
 |  |                  if(self.completion != nil){
 | 
											
												
													
														|  |                      self.completion?()
 |  |                      self.completion?()
 | 
											
												
													
														|  |                  }
 |  |                  }
 | 
											
										
											
												
													
														|  | @@ -266,7 +276,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |                  if !mIsExport {
 |  |                  if !mIsExport {
 | 
											
												
													
														|  |                      self.start(isFreeBuffer: true,timeRange: playeTimeRange)
 |  |                      self.start(isFreeBuffer: true,timeRange: playeTimeRange)
 | 
											
												
													
														|  |                  }else{
 |  |                  }else{
 | 
											
												
													
														|  | -                    BFLog(message: "强制停止!!!!")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                    FilterLog(message: "强制停止!!!!")
 | 
											
												
													
														|  |                      displayLink.isPaused = true
 |  |                      displayLink.isPaused = true
 | 
											
												
													
														|  |                      return
 |  |                      return
 | 
											
												
													
														|  |                  }
 |  |                  }
 | 
											
										
											
												
													
														|  | @@ -276,9 +286,9 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |                  self.conditionLock.lock()
 |  |                  self.conditionLock.lock()
 | 
											
												
													
														|  |                  while self.readingShouldWait {
 |  |                  while self.readingShouldWait {
 | 
											
												
													
														|  |                      self.synchronizedEncodingDebugPrint("Disable reading")
 |  |                      self.synchronizedEncodingDebugPrint("Disable reading")
 | 
											
												
													
														|  | -                    BFLog(2, message: "Disable reading 开始等待 \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0)) ")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                    FilterLog(2, message: "Disable reading 开始等待 \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0)) ")
 | 
											
												
													
														|  |                      self.conditionLock.wait()
 |  |                      self.conditionLock.wait()
 | 
											
												
													
														|  | -                    BFLog(2, message: "Enable reading  停止等待 \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                    FilterLog(2, message: "Enable reading  停止等待 \(CFAbsoluteTimeGetCurrent() - (debugStartTime ?? 0.0))")
 | 
											
												
													
														|  |                  }
 |  |                  }
 | 
											
												
													
														|  |                  self.conditionLock.unlock()
 |  |                  self.conditionLock.unlock()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -311,11 +321,11 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |      @objc public func start(isFreeBuffer: Bool, isExport: Bool = false,timeRange:CMTimeRange = CMTimeRange.init()) {
 |  |      @objc public func start(isFreeBuffer: Bool, isExport: Bool = false,timeRange:CMTimeRange = CMTimeRange.init()) {
 | 
											
												
													
														|  |          
 |  |          
 | 
											
												
													
														|  |          debugStartTime = CFAbsoluteTimeGetCurrent()
 |  |          debugStartTime = CFAbsoluteTimeGetCurrent()
 | 
											
												
													
														|  | -        BFLog(2, message: "开始播放的系统时钟时间 \(String(describing: debugStartTime))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "开始播放的系统时钟时间 \(String(describing: debugStartTime))")
 | 
											
												
													
														|  |          
 |  |          
 | 
											
												
													
														|  |          playeTimeRange = timeRange
 |  |          playeTimeRange = timeRange
 | 
											
												
													
														|  |          readerAudioTrackOutput = nil
 |  |          readerAudioTrackOutput = nil
 | 
											
												
													
														|  | -        BFLog(2, message: "PQMoveInput开始")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "PQMoveInput开始")
 | 
											
												
													
														|  |          mFreeBuffer = isFreeBuffer
 |  |          mFreeBuffer = isFreeBuffer
 | 
											
												
													
														|  |          assetReader = createReader()
 |  |          assetReader = createReader()
 | 
											
												
													
														|  |      
 |  |      
 | 
											
										
											
												
													
														|  | @@ -323,16 +333,16 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          isPlay = true
 |  |          isPlay = true
 | 
											
												
													
														|  |          if assetReader == nil {
 |  |          if assetReader == nil {
 | 
											
												
													
														|  | -            BFLog(2, message: "assetReader is null!!!!!")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "assetReader is null!!!!!")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          mIsExport = isExport
 |  |          mIsExport = isExport
 | 
											
												
													
														|  |          do {
 |  |          do {
 | 
											
												
													
														|  |              try NSObject.catchException { [self] in
 |  |              try NSObject.catchException { [self] in
 | 
											
												
													
														|  | -                if(mIsExport){
 |  | 
 | 
											
												
													
														|  | 
 |  | +                if(!isUsedAVPlayer){
 | 
											
												
													
														|  |                      guard self.assetReader.startReading() else {
 |  |                      guard self.assetReader.startReading() else {
 | 
											
												
													
														|  | -                        BFLog(2, message: "ERROR: Unable to start reading: \(String(describing: self.assetReader.error))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                        FilterLog(2, message: "ERROR: Unable to start reading: \(String(describing: self.assetReader.error))")
 | 
											
												
													
														|  |                          return
 |  |                          return
 | 
											
												
													
														|  |                      }
 |  |                      }
 | 
											
												
													
														|  |                  }else{
 |  |                  }else{
 | 
											
										
											
												
													
														|  | @@ -344,19 +354,19 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |                
 |  |                
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |          } catch {
 |  |          } catch {
 | 
											
												
													
														|  | -            BFLog(2, message: "ERROR: Unable to start reading: \(error)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "ERROR: Unable to start reading: \(error)")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        BFLog(2, message: "assetReader.outputs count is \(assetReader.outputs)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "assetReader.outputs count is \(assetReader.outputs)")
 | 
											
												
													
														|  |          for output in assetReader.outputs {
 |  |          for output in assetReader.outputs {
 | 
											
												
													
														|  |              if output.mediaType == AVMediaType.video {
 |  |              if output.mediaType == AVMediaType.video {
 | 
											
												
													
														|  |                  readerVideoTrackOutput = output
 |  |                  readerVideoTrackOutput = output
 | 
											
												
													
														|  | -                BFLog(2, message: " set  readerVideoTrackOutput")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(2, message: " set  readerVideoTrackOutput")
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |              if output.mediaType == AVMediaType.audio {
 |  |              if output.mediaType == AVMediaType.audio {
 | 
											
												
													
														|  |                  readerAudioTrackOutput = output
 |  |                  readerAudioTrackOutput = output
 | 
											
												
													
														|  | -                BFLog(2, message: " set  readerAudioTrackOutput")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(2, message: " set  readerAudioTrackOutput")
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -373,11 +383,11 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      public func cancel() {
 |  |      public func cancel() {
 | 
											
												
													
														|  | -        BFLog(2, message: "PQMoveInput取消")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "PQMoveInput取消")
 | 
											
												
													
														|  |          isPlay = false
 |  |          isPlay = false
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          // 将定时器移除主循环
 |  |          // 将定时器移除主循环
 | 
											
												
													
														|  | -        displayLink?.remove(from: RunLoop.main, forMode: RunLoop.Mode.default)
 |  | 
 | 
											
												
													
														|  | 
 |  | +        displayLink?.remove(from: RunLoop.main, forMode: RunLoop.Mode.common)
 | 
											
												
													
														|  |          // 停止定时器
 |  |          // 停止定时器
 | 
											
												
													
														|  |          displayLink?.invalidate()
 |  |          displayLink?.invalidate()
 | 
											
												
													
														|  |          displayLink = nil
 |  |          displayLink = nil
 | 
											
										
											
												
													
														|  | @@ -388,7 +398,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      public func resume() {
 |  |      public func resume() {
 | 
											
												
													
														|  | -        BFLog(2, message: "PQMoveInput恢复播放")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "PQMoveInput恢复播放")
 | 
											
												
													
														|  |          mFreeBuffer = false
 |  |          mFreeBuffer = false
 | 
											
												
													
														|  |          isPlay = true
 |  |          isPlay = true
 | 
											
												
													
														|  |          if !mIsExport{
 |  |          if !mIsExport{
 | 
											
										
											
												
													
														|  | @@ -403,15 +413,15 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      public func pause() {
 |  |      public func pause() {
 | 
											
												
													
														|  |          if !isPlay {
 |  |          if !isPlay {
 | 
											
												
													
														|  | -            BFLog(2, message: "还不是播放状态")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "还不是播放状态")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          if displayLink == nil {
 |  |          if displayLink == nil {
 | 
											
												
													
														|  | -            BFLog(2, message: "displayLink is erorr displaye bug !!!!")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "displayLink is erorr displaye bug !!!!")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  | -        BFLog(2, message: "PQMoveInput暂停 displayLink.timestamp:  \(displayLink!.timestamp)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "PQMoveInput暂停 displayLink.timestamp:  \(displayLink!.timestamp)")
 | 
											
												
													
														|  |          isPlay = false
 |  |          isPlay = false
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          // 暂停帧的刷新 true:停 ; false:开始
 |  |          // 暂停帧的刷新 true:停 ; false:开始
 | 
											
										
											
												
													
														|  | @@ -427,7 +437,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |              startTime = currentTime
 |  |              startTime = currentTime
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -        BFLog(2, message: "暂停时间:\(currTime)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "暂停时间:\(currTime)")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |          beginTime = 0
 |  |          beginTime = 0
 | 
											
												
													
														|  |          
 |  |          
 | 
											
										
											
												
													
														|  | @@ -443,10 +453,10 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |      func createReader() -> AVAssetReader? {
 |  |      func createReader() -> AVAssetReader? {
 | 
											
												
													
														|  |          do {
 |  |          do {
 | 
											
												
													
														|  |              let assetReader = try AVAssetReader(asset: asset)
 |  |              let assetReader = try AVAssetReader(asset: asset)
 | 
											
												
													
														|  | -            BFLog(2, message: "assetReader init \(assetReader)  asset url is \(asset)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "assetReader init \(assetReader)  asset url is \(asset)")
 | 
											
												
													
														|  |              if audioMix == nil {
 |  |              if audioMix == nil {
 | 
											
												
													
														|  |                  if let audioTrack = asset.tracks(withMediaType: .audio).first, let _ = audioEncodingTarget {
 |  |                  if let audioTrack = asset.tracks(withMediaType: .audio).first, let _ = audioEncodingTarget {
 | 
											
												
													
														|  | -                    BFLog(1, message: "audioTrack start \(audioTrack.timeRange.start) \(audioTrack.timeRange.duration.value)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                    FilterLog(1, message: "audioTrack start \(audioTrack.timeRange.start) \(audioTrack.timeRange.duration.value)")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |                      let readerAudioTrackOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: audioSettings)
 |  |                      let readerAudioTrackOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: audioSettings)
 | 
											
												
													
														|  |                      readerAudioTrackOutput.alwaysCopiesSampleData = false
 |  |                      readerAudioTrackOutput.alwaysCopiesSampleData = false
 | 
											
										
											
												
													
														|  | @@ -457,7 +467,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |                  }
 |  |                  }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              } else {
 |  |              } else {
 | 
											
												
													
														|  | -                BFLog(2, message: "self.asset.tracks is \(asset.tracks.count)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(2, message: "self.asset.tracks is \(asset.tracks.count)")
 | 
											
												
													
														|  |                  let readerAudioTrackOutput = AVAssetReaderAudioMixOutput(audioTracks: asset.tracks(withMediaType: .audio), audioSettings: audioSettings)
 |  |                  let readerAudioTrackOutput = AVAssetReaderAudioMixOutput(audioTracks: asset.tracks(withMediaType: .audio), audioSettings: audioSettings)
 | 
											
												
													
														|  |                  readerAudioTrackOutput.audioMix = audioMix
 |  |                  readerAudioTrackOutput.audioMix = audioMix
 | 
											
												
													
														|  |                  readerAudioTrackOutput.alwaysCopiesSampleData = false
 |  |                  readerAudioTrackOutput.alwaysCopiesSampleData = false
 | 
											
										
											
												
													
														|  | @@ -465,21 +475,21 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              assetReader.timeRange = playeTimeRange
 |  |              assetReader.timeRange = playeTimeRange
 | 
											
												
													
														|  | -            BFLog(2, message: "初始化播放器开始时间\(CMTimeGetSeconds(assetReader.timeRange.start)) 结束时间\(CMTimeGetSeconds(assetReader.timeRange.end)) 音乐的总时长\(asset.duration.seconds)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "初始化播放器开始时间\(CMTimeGetSeconds(assetReader.timeRange.start)) 结束时间\(CMTimeGetSeconds(assetReader.timeRange.end)) 音乐的总时长\(asset.duration.seconds)")
 | 
											
												
													
														|  |         
 |  |         
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              actualStartTime = nil
 |  |              actualStartTime = nil
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              return assetReader
 |  |              return assetReader
 | 
											
												
													
														|  |          } catch {
 |  |          } catch {
 | 
											
												
													
														|  | -            BFLog(2, message: "ERROR: Unable to create asset reader: \(error)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "ERROR: Unable to create asset reader: \(error)")
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          return nil
 |  |          return nil
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      func readNextVideoFrame(with _: AVAssetReader) {
 |  |      func readNextVideoFrame(with _: AVAssetReader) {
 | 
											
												
													
														|  |          
 |  |          
 | 
											
												
													
														|  | -        BFLog(2, message: "视频解码状态\(assetReader.status.rawValue)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "视频解码状态\(assetReader.status.rawValue)")
 | 
											
												
													
														|  |       
 |  |       
 | 
											
												
													
														|  |          autoreleasepool {
 |  |          autoreleasepool {
 | 
											
												
													
														|  |              synchronizedEncodingDebugPrint("Process frame input")
 |  |              synchronizedEncodingDebugPrint("Process frame input")
 | 
											
										
											
												
													
														|  | @@ -491,7 +501,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |              
 |  |              
 | 
											
												
													
														|  |      
 |  |      
 | 
											
												
													
														|  |              let prgressValue = (currTime - start) / (duration - start)
 |  |              let prgressValue = (currTime - start) / (duration - start)
 | 
											
												
													
														|  | -//            BFLog(1, message: "\(mIsExport) movinput 当前时间 is \(currTime) curr当前进度:\(prgressValue)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +//            FilterLog(1, message: "\(mIsExport) movinput 当前时间 is \(currTime) curr当前进度:\(prgressValue)")
 | 
											
												
													
														|  |              progress?(currTime, duration, prgressValue)
 |  |              progress?(currTime, duration, prgressValue)
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              sharedImageProcessingContext.runOperationSynchronously { [weak self] in
 |  |              sharedImageProcessingContext.runOperationSynchronously { [weak self] in
 | 
											
										
											
												
													
														|  | @@ -502,13 +512,13 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |      func readNextAudioSample(with assetReader: AVAssetReader, from audioTrackOutput: AVAssetReaderOutput) {
 |  |      func readNextAudioSample(with assetReader: AVAssetReader, from audioTrackOutput: AVAssetReaderOutput) {
 | 
											
												
													
														|  |          
 |  |          
 | 
											
												
													
														|  | -        if(!mIsExport){
 |  | 
 | 
											
												
													
														|  | -            BFLog(2, message: "不是导出模式")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        if(isUsedAVPlayer){
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "使用的 avplayer 播放模式")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |         
 |  |         
 | 
											
												
													
														|  |          if !isPlay {
 |  |          if !isPlay {
 | 
											
												
													
														|  | -            BFLog(2, message: "自动停到首帧的不处理音频")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "自动停到首帧的不处理音频")
 | 
											
												
													
														|  |              return
 |  |              return
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          /*
 |  |          /*
 | 
											
										
											
												
													
														|  | @@ -517,35 +527,35 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |           case failed = 3
 |  |           case failed = 3
 | 
											
												
													
														|  |           case cancelled = 4
 |  |           case cancelled = 4
 | 
											
												
													
														|  |           */
 |  |           */
 | 
											
												
													
														|  | -        BFLog(2, message: "音频解码状态\(assetReader.status.rawValue)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +        FilterLog(2, message: "音频解码状态\(assetReader.status.rawValue)")
 | 
											
												
													
														|  |          
 |  |          
 | 
											
												
													
														|  |          autoreleasepool {
 |  |          autoreleasepool {
 | 
											
												
													
														|  |              guard let sampleBuffer = audioTrackOutput.copyNextSampleBuffer(),CMSampleBufferIsValid(sampleBuffer) else {
 |  |              guard let sampleBuffer = audioTrackOutput.copyNextSampleBuffer(),CMSampleBufferIsValid(sampleBuffer) else {
 | 
											
												
													
														|  |                  if(assetReader.status == .completed){
 |  |                  if(assetReader.status == .completed){
 | 
											
												
													
														|  | -                    BFLog(2, message: "提前结束的了!!!!\(String(describing: assetReader.error))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                    FilterLog(2, message: "提前结束的了!!!!\(String(describing: assetReader.error))")
 | 
											
												
													
														|  |                  }
 |  |                  }
 | 
											
												
													
														|  |                  if let movieOutput = synchronizedMovieOutput {
 |  |                  if let movieOutput = synchronizedMovieOutput {
 | 
											
												
													
														|  | -                    BFLog(2, message: "this is runing assetWriterAudioInput  markAsFinished \(String(describing: assetReader.error)) \(assetReader)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                    FilterLog(2, message: "this is runing assetWriterAudioInput  markAsFinished \(String(describing: assetReader.error)) \(assetReader)")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |                      movieOutput.movieProcessingContext.runOperationAsynchronously {
 |  |                      movieOutput.movieProcessingContext.runOperationAsynchronously {
 | 
											
												
													
														|  |                          movieOutput.audioEncodingIsFinished = true
 |  |                          movieOutput.audioEncodingIsFinished = true
 | 
											
												
													
														|  |                          movieOutput.assetWriterAudioInput?.markAsFinished()
 |  |                          movieOutput.assetWriterAudioInput?.markAsFinished()
 | 
											
												
													
														|  |                      }
 |  |                      }
 | 
											
												
													
														|  |                  }
 |  |                  }
 | 
											
												
													
														|  | -                BFLog(2, message: "sampleBuffer is null 速度太快copy is error")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(2, message: "sampleBuffer is null 速度太快copy is error")
 | 
											
												
													
														|  |                  return
 |  |                  return
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              synchronizedEncodingDebugPrint("Process audio sample input")
 |  |              synchronizedEncodingDebugPrint("Process audio sample input")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              let currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer)
 |  |              let currentSampleTime = CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer)
 | 
											
												
													
														|  | -            BFLog(2, message: "处理音频的时间戳 \(CMTimeGetSeconds(currentSampleTime)) 播放时间\(CMTimeGetSeconds(currentTime))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(2, message: "处理音频的时间戳 \(CMTimeGetSeconds(currentSampleTime)) 播放时间\(CMTimeGetSeconds(currentTime))")
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              // https://www.itdaan.com/blog/2013/11/28/deb10f90970a5ea33f185c9faf2a0ab3.html
 |  |              // https://www.itdaan.com/blog/2013/11/28/deb10f90970a5ea33f185c9faf2a0ab3.html
 | 
											
												
													
														|  |              if !mFreeBuffer {
 |  |              if !mFreeBuffer {
 | 
											
												
													
														|  |                  audioEncodingTarget?.processAudioBuffer(sampleBuffer)
 |  |                  audioEncodingTarget?.processAudioBuffer(sampleBuffer)
 | 
											
												
													
														|  |              }else{
 |  |              }else{
 | 
											
												
													
														|  | -                BFLog(message: "不播放音频!!!!")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(message: "不播放音频!!!!")
 | 
											
												
													
														|  |              }
 |  |              }
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
										
											
												
													
														|  | @@ -555,7 +565,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |              let startPTime = CFAbsoluteTimeGetCurrent()
 |  |              let startPTime = CFAbsoluteTimeGetCurrent()
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |              imageFramebuffer.lock()
 |  |              imageFramebuffer.lock()
 | 
											
												
													
														|  | -            BFLog(message: "mIsExport:\(mIsExport) 实际设置的每一帧时间戳:\(CMTimeGetSeconds(currentTime))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(message: "mIsExport:\(mIsExport) 实际设置的每一帧时间戳:\(CMTimeGetSeconds(currentTime))")
 | 
											
												
													
														|  |              // 设置当前帧的时间戳
 |  |              // 设置当前帧的时间戳
 | 
											
												
													
														|  |              imageFramebuffer.timingStyle = .videoFrame(timestamp: Timestamp(currentTime))
 |  |              imageFramebuffer.timingStyle = .videoFrame(timestamp: Timestamp(currentTime))
 | 
											
												
													
														|  |   
 |  |   
 | 
											
										
											
												
													
														|  | @@ -572,7 +582,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |                  totalFrameTimeDuringCapture += currentFrameTime
 |  |                  totalFrameTimeDuringCapture += currentFrameTime
 | 
											
												
													
														|  |                  
 |  |                  
 | 
											
												
													
														|  |                  
 |  |                  
 | 
											
												
													
														|  | -                BFLog(2, message: "currentTime is \(String(format: "%.6f", CMTimeGetSeconds(currentTime))) 当前帧渲染时间 : \(String(format: "%.6f",1000.0 * currentFrameTime)) ms Average frame time : \(String(format: "%.6f", 1000.0 * totalFrameTimeDuringCapture / Double(totalFramesSent))) ms  totalFrameTimeDuringCapture is \(String(format: "%.6f",totalFrameTimeDuringCapture))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +                FilterLog(2, message: "currentTime is \(String(format: "%.6f", CMTimeGetSeconds(currentTime))) 当前帧渲染时间 : \(String(format: "%.6f",1000.0 * currentFrameTime)) ms Average frame time : \(String(format: "%.6f", 1000.0 * totalFrameTimeDuringCapture / Double(totalFramesSent))) ms  totalFrameTimeDuringCapture is \(String(format: "%.6f",totalFrameTimeDuringCapture))")
 | 
											
												
													
														|  |               
 |  |               
 | 
											
												
													
														|  |              
 |  |              
 | 
											
												
													
														|  |  
 |  |  
 | 
											
										
											
												
													
														|  | @@ -628,7 +638,7 @@ public class PQMovieInput: ImageSource {
 | 
											
												
													
														|  |              conditionLock.signal()
 |  |              conditionLock.signal()
 | 
											
												
													
														|  |              
 |  |              
 | 
											
												
													
														|  |          } else {
 |  |          } else {
 | 
											
												
													
														|  | -            BFLog(1, message: "MovieOutput total frames appended 要加锁了")
 |  | 
 | 
											
												
													
														|  | 
 |  | +            FilterLog(1, message: "MovieOutput total frames appended 要加锁了")
 | 
											
												
													
														|  |              readingShouldWait = true
 |  |              readingShouldWait = true
 | 
											
												
													
														|  |          }
 |  |          }
 | 
											
												
													
														|  |          conditionLock.unlock()
 |  |          conditionLock.unlock()
 | 
											
										
											
												
													
														|  | @@ -720,7 +730,7 @@ extension PQMovieInput {
 | 
											
												
													
														|  |                  let range = strongSelf.musicPlayRanges?[strongSelf.indexRage]
 |  |                  let range = strongSelf.musicPlayRanges?[strongSelf.indexRage]
 | 
											
												
													
														|  |                  playerItem.forwardPlaybackEndTime = range!.end
 |  |                  playerItem.forwardPlaybackEndTime = range!.end
 | 
											
												
													
														|  |                  playerItem.reversePlaybackEndTime = range!.start
 |  |                  playerItem.reversePlaybackEndTime = range!.start
 | 
											
												
													
														|  | -//                BFLog(1, message: "curr: start ********************\(CMTimeGetSeconds(range.start)) - \(playerItem.reversePlaybackEndTime) - \(playerItem.forwardPlaybackEndTime)")
 |  | 
 | 
											
												
													
														|  | 
 |  | +//                FilterLog(1, message: "curr: start ********************\(CMTimeGetSeconds(range.start)) - \(playerItem.reversePlaybackEndTime) - \(playerItem.forwardPlaybackEndTime)")
 | 
											
												
													
														|  |                  strongSelf.avPlayer!.seek(to: playerItem.reversePlaybackEndTime) { isSuccess in
 |  |                  strongSelf.avPlayer!.seek(to: playerItem.reversePlaybackEndTime) { isSuccess in
 | 
											
												
													
														|  |                      playerItem.seek(to: playerItem.reversePlaybackEndTime) { isSuccess in
 |  |                      playerItem.seek(to: playerItem.reversePlaybackEndTime) { isSuccess in
 | 
											
												
													
														|  |                          strongSelf.avPlayer!.play()
 |  |                          strongSelf.avPlayer!.play()
 | 
											
										
											
												
													
														|  | @@ -733,7 +743,7 @@ extension PQMovieInput {
 | 
											
												
													
														|  |          
 |  |          
 | 
											
												
													
														|  |  //        avPlayerTimeObserver = avPlayer!.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 4), queue: DispatchQueue.global()) {[weak self] time in
 |  |  //        avPlayerTimeObserver = avPlayer!.addPeriodicTimeObserver(forInterval: CMTime(value: 1, timescale: 4), queue: DispatchQueue.global()) {[weak self] time in
 | 
											
												
													
														|  |  //         //    进度监控
 |  |  //         //    进度监控
 | 
											
												
													
														|  | -//            BFLog(1, message: "cont:\(CMTimeGetSeconds(time) - CMTimeGetSeconds((self?.musicPlayRanges?.first!.start)!)), curr:\(CMTimeGetSeconds(time))")
 |  | 
 | 
											
												
													
														|  | 
 |  | +//            FilterLog(1, message: "cont:\(CMTimeGetSeconds(time) - CMTimeGetSeconds((self?.musicPlayRanges?.first!.start)!)), curr:\(CMTimeGetSeconds(time))")
 | 
											
												
													
														|  |  //        } as? NSKeyValueObservation
 |  |  //        } as? NSKeyValueObservation
 | 
											
												
													
														|  |      }
 |  |      }
 | 
											
												
													
														|  |      
 |  |      
 |