swift 如何使用AVPlayer镜像(翻转)视频播放?

dohp0rv5  于 2023-01-19  发布在  Swift
关注(0)|答案(2)|浏览(273)

我想使用AVPlayer镜像(翻转)视频播放。例如:镜筒:-https://chrome.google.com/webstore/detail/mirrortube/olomckflnlligkboahmaihmeaffjdbfm/related?hl=en
我想实现相同的功能。
我已经尝试更改CGAffineTransform,但它的工作原理不一样。
先谢了!

afdcj2ne

afdcj2ne1#

下面是如何使用CGAffineTransform垂直和水平翻转播放器的示例:

播放器视图

import AVKit

class PlayerView: UIView {
    var player: AVPlayer? {
        get {
            return playerLayer.player
        }
        set {
            playerLayer.player = newValue
        }
    }

    var playerLayer: AVPlayerLayer {
        return layer as! AVPlayerLayer
    }

    // Override UIView property
    override static var layerClass: AnyClass {
        return AVPlayerLayer.self
    }
}

使用xib/storyboard中定义的播放器视图的视图控制器

@IBOutlet var playerView: PlayerView!

@IBAction func flipVerticallyBarButtonItemTouched(_ sender: UIBarButtonItem) {
           UIView.animate(withDuration: 0.2) { [unowned self] in
               self.playerView.transform = self.playerView.transform.concatenating(CGAffineTransform(scaleX: 1, y: -1))
           }
       }
@IBAction func flipHorizontallyBarButtonItemTouched(_ sender: UIBarButtonItem) {
           UIView.animate(withDuration: 0.2) { [unowned self] in
            self.playerView.transform = self.playerView.transform.concatenating(CGAffineTransform(scaleX: -1, y: 1))
           }
}
hi3rlvi2

hi3rlvi22#

注意:对于Mac Catalyst中的iOS应用程序(具有AVPlayerController子类),根视图是AVPlayerView。但奇怪的是,AVPlayerView在iOS〉Mac Catalyst中不是公共的,因此self.playerView无法工作,因此您无法对其进行转换。您得到的类未找到“AVPlayerView”
但是当你在Mac Catalyst中运行应用程序并检查它时,self.view是一个AVPlayerView
解决方法只是翻转根视图本身,而不转换- self.view

`class MyAVPlayerController: AVPlayerController`

to flip horizontal etc

            self.view.transform = self.view.transform.concatenating(CGAffineTransform(scaleX: -1, y: 1))

to flip vertical etc

            self.view.transform = self.view.transform.concatenating(CGAffineTransform(scaleX: 1, y: -1))

KNOWN ISSUE this flips the whole AVPlayerView including controls. in iOS 16 the actual player is a view where Swift.type(of:view) is "__AVPlayerLayerView" so you can walk the hierarchy and find the UIView return it then apply the transform to only that subview



func flipHorizontal(){
    
    print("TradAVPlayerViewController.swift flipHorizontal")
    
    if self.player != nil{
        //------------------------------------------------------------------
        //v1 - flips VC.view which is AVPlayerView
        //but also flips TOAST and CONTROLS
        //https://developer.apple.com/documentation/uikit/uiview/1622459-transform
        //------------------------------------------------------------------
        //OK ROTATES VIEW
        //self.view.transform = CGAffineTransform(rotationAngle: CGFloat((90 * Double.pi)/180))
        
        //OK FLIP VERTICAL
        //self.view.transform = self.view.transform.concatenating(CGAffineTransform(scaleX: 1, y: -1))
        
        //OK FLIPS HORIZONTAL
 //       self.view.transform = self.view.transform.concatenating(CGAffineTransform(scaleX: -1, y: 1))

        //note the flip remains in place as long as self.player isnt recreated so PREV/NEXT will stay flipped
        
        //------------------------------------------------------------------
        //ISSUE flipping the whole view also flips the TOAST and SCRUBBER
        //------------------------------------------------------------------
        //in iOS 15 the player is a class with name "__AVPlayerLayerView"
        //find it in the hierarchy and only apply transform to that on
        if let rootView = self.view{
            let className = "__AVPlayerLayerView"
            if let subViewFound
                = findSubViewByName(name: className,
                                    view: rootView)
            {
                print("FOUND className:'\(className)' flipping it")
                
                subViewFound.transform = subViewFound.transform.concatenating(CGAffineTransform(scaleX: -1, y: 1))
            }else{
                print("NOT FOUND className:'\(className)' CANT FLIP IT - debug hierarchy in 3d and get class name for the AVPlayerLayerView")
            }
        }else{
            logger.error("self.view is nil")
        }
        
        print()
    }else{
        logger.error("self.player is nil")
    }
}

func findSubViewByName(name: String, view: UIView) -> UIView?{
    var viewFound: UIView? = nil
    
    for subView in view.subviews{
    
        //MUST WRAP IN STRING else types wont match
        let typeName = "\(Swift.type(of: subView))"
        //print("typeName:\(typeName)")
        
        if typeName == name {
            print("SUB VIEW - typeName:\(typeName) - MATCH!!")
            viewFound = subView
            break
            
        }else{
            print("SUB VIEW - typeName:\(typeName) - NO MATCH")
        }
        
        //recurse depth first
        
        
        if let subViewFound = findSubViewByName(name: name, view: subView){
            viewFound = subViewFound
            break
        }else{
            //no match in subviewsf
        }
    }
    
    return viewFound
}

相关问题