播放视频带有音频;来自资产以及录制视频和音频来自前置摄像头?

问题描述

我不知道这是否可能,但是实现该目标有一个问题。

我有一个UIView的{​​{1}}(VideoView),并播放资产中的一些视频并拥有自己的音频。

在此视图上,还有另一个(较小的)UIView(CameraView),具有:

  • AVCaptureVideoPreviewLayer(显示前置摄像头)
  • AVCaptureSession
  • AVCaptureDevice
  • AVAudioSession

显示用户前置摄像头的预览并录制自己的音频和视频。

并同时运行。与FaceTime通话类似。

AVPlayerLayer中的

AVAudioSession设置如下:

CameraView

但是,尽管如此,我在播放视频(VideoView)的录制视频(由CameraView录制)中仍有某种回声。

我已经尝试过单独保存音频,但是问题是相同的。 这是我的第一个AV *应用程序,我对音频/视频没有太多经验。 有人可以指出我的错误在哪里或指向正确的方向...

Sample Screenshot

VideView.swift

let audioSession = AVAudioSession.sharedInstance()
do {
  if #available(iOS 11.0,*) {
     try audioSession.setCategory(.playAndRecord,mode: .spokenAudio,policy: AVAudioSession.RouteSharingPolicy.default,options: [.duckOthers])
  } else {
    try audioSession.setCategory(.playAndRecord,mode: .spokenAudio)
  }
  try audioSession.setActive(true)
} catch let error {
  print("Audio setup error",#file,#function,#line,error.localizedDescription)
}

CameraView.swift

protocol VideoViewDelegate {
    func didEndVideo()
    func didEndVideo(of instance: VideoView)
    func isVideoReady()
}

class VideoView: UIView {
    
    var playerLayer: AVPlayerLayer?
    var player: AVPlayer?
    var isLoop: Bool = false
    
    var delegate: VideoViewDelegate!
    
    var observer: NSKeyValueObservation?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        backgroundColor = .black
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    func ply(for url: URL) {
        player = AVPlayer(url: url)
        playerLayer = AVPlayerLayer(player: player)
        playerLayer?.frame = bounds
        playerLayer?.videoGravity = AVLayerVideoGravity.resizeAspectFill
        
        if let playerLayer = self.playerLayer {
            layer.addSublayer(playerLayer)
        }
        
        NotificationCenter.default.addObserver(self,selector: #selector(reachTheEndOfTheVideo),name: NSNotification.Name.AVPlayerItemDidPlayToEndTime,object: self.player?.currentItem)
    }
    
    func prepare(url: URL) {
        player?.replaceCurrentItem(with: AVPlayerItem(url: url))
        NotificationCenter.default.addObserver(self,object: self.player?.currentItem)
    }
    
    func destroyMe() {
        stop()
        NotificationCenter.default.removeObserver(self)
        observer?.invalidate()
    }
    
    func play() {
        if player?.timeControlStatus != AVPlayer.TimeControlStatus.playing {
            player?.play()
        }
    }
    
    func pause() {
        player?.pause()
    }
    
    func stop() {
        player?.pause()
        player?.seek(to: CMTime.zero)
    }
    
    @objc
    func reachTheEndOfTheVideo(_ notification: Notification) {
        if isLoop {
            player?.pause()
            player?.seek(to: CMTime.zero)
            player?.play()
        } else {
            player?.pause()
            player?.seek(to: CMTime.zero)
            
            UIView.animate(withDuration: 0.4) { [weak self] in
                self!.transform = .identity
            }
            if delegate != nil { delegate.didEndVideo() }
            if delegate != nil { delegate.didEndVideo(of: self) }
        }
    }
}

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...