I am trying to rotate avplayer but when i rotate it ,it is rotated from the beginning,i want to rotate while i am playing it at any time and it should rotate from there.I am
Swift 5 Version
func rotateVideoPlayer(player: AVPlayer, degrees: CGFloat) -> AVPlayer? {
let urlAsset = player.currentItem?.asset as! AVURLAsset
let url = urlAsset.url
var composition: AVMutableComposition?
var videoComposition: AVMutableVideoComposition?
var instruction: AVMutableVideoCompositionInstruction?
let asset = AVURLAsset(url: url)
var layerInstruction: AVMutableVideoCompositionLayerInstruction?
var t1: CGAffineTransform?
var t2: CGAffineTransform?
var assetVideoTrack: AVAssetTrack?
var assetAudioTrack: AVAssetTrack?
if asset.tracks(withMediaType: AVMediaType.video).count != 0 {
assetVideoTrack = asset.tracks(withMediaType: AVMediaType.video)[0]
}
if asset.tracks(withMediaType: AVMediaType.audio).count != 0 {
assetAudioTrack = asset.tracks(withMediaType: AVMediaType.audio)[0]
}
let insertionPoint = CMTime.invalid
composition = AVMutableComposition()
if assetVideoTrack != nil {
let compositionVideoTrack: AVMutableCompositionTrack = (composition?.addMutableTrack(withMediaType: AVMediaType.video, preferredTrackID: kCMPersistentTrackID_Invalid))!
let timeRange = CMTimeRangeMake(start: CMTime.zero, duration: asset.duration)
try! compositionVideoTrack.insertTimeRange(timeRange, of: assetVideoTrack!, at: insertionPoint)
}
if assetAudioTrack != nil {
let compositionAudioTrack: AVMutableCompositionTrack = (composition?.addMutableTrack(withMediaType: AVMediaType.audio, preferredTrackID: kCMPersistentTrackID_Invalid))!
let timeRange = CMTimeRangeMake(start: CMTime.zero, duration: asset.duration)
try! compositionAudioTrack.insertTimeRange(timeRange, of: assetAudioTrack!, at: insertionPoint)
}
let width = Float((assetVideoTrack?.naturalSize.width)!)
let height = Float((assetVideoTrack?.naturalSize.height)!)
let toDiagonal = Float(sqrt(width * width + height * height))
let toDiagonalAngle = Float(radiansToDegrees(acosf(width/toDiagonal)))
let toDiagonalAngle2 = Float(90 - radiansToDegrees(acosf(width/toDiagonal)))
var toDiagonalAngleComple: Float
var toDiagonalAngleComple2: Float
var finalHeight: Float = 0
var finalWidth: Float = 0
if degrees >= 0 && degrees <= 90 {
toDiagonalAngleComple = toDiagonalAngle + Float(degrees)
toDiagonalAngleComple2 = toDiagonalAngle2 + Float(degrees)
let sinfValue = sinf(degreesToRadians(toDiagonalAngleComple))
let sinfValue2 = sinf(degreesToRadians(toDiagonalAngleComple2))
finalHeight = abs(toDiagonal * sinfValue)
finalWidth = abs(toDiagonal * sinfValue2)
let side1 = height * sinf(degreesToRadians(Float(degrees)))
let side2 = 0.0
t1 = CGAffineTransform(translationX: CGFloat(side1), y: CGFloat(side2))
} else if degrees > 90 && degrees <= 180 {
let degrees2 = Float(degrees - 90)
toDiagonalAngleComple = toDiagonalAngle + degrees2
toDiagonalAngleComple2 = toDiagonalAngle2 + degrees2
let sinfValue = sinf(degreesToRadians(toDiagonalAngleComple2))
let sinfValue2 = sinf(degreesToRadians(toDiagonalAngleComple))
finalHeight = abs(toDiagonal * sinfValue)
finalWidth = abs(toDiagonal * sinfValue2)
let side1 = width * sinf(degreesToRadians(degrees2)) + height * cosf(degreesToRadians(degrees2))
let side2 = height * sinf(degreesToRadians(degrees2))
t1 = CGAffineTransform(translationX: CGFloat(side1), y: CGFloat(side2))
} else if degrees >= -90 && degrees < 0 {
let degrees2 = Float(degrees - 90)
let degrees2abs = Float(abs(degrees))
toDiagonalAngleComple = toDiagonalAngle + degrees2
toDiagonalAngleComple2 = toDiagonalAngle2 + degrees2
let sinfValue = sinf(degreesToRadians(toDiagonalAngleComple2))
let sinfValue2 = sinf(degreesToRadians(toDiagonalAngleComple))
finalHeight = abs(toDiagonal * sinfValue)
finalWidth = abs(toDiagonal * sinfValue2)
let side1 = 0
let side2 = width * sinf(degreesToRadians(degrees2abs))
t1 = CGAffineTransform(translationX: CGFloat(side1), y: CGFloat(side2))
} else if degrees >= -180 && degrees < -90 {
let degreesabs = Float(abs(degrees))
let degreesPlus = degreesabs - 90
toDiagonalAngleComple = toDiagonalAngle + Float(degrees)
toDiagonalAngleComple2 = toDiagonalAngle2 + Float(degrees)
let sinfValue = sinf(degreesToRadians(toDiagonalAngleComple))
let sinfValue2 = sinf(degreesToRadians(toDiagonalAngleComple2))
finalHeight = abs(toDiagonal * sinfValue)
finalWidth = abs(toDiagonal * sinfValue2)
let side1 = width * sinf(degreesToRadians(degreesPlus))
let side2 = height * sinf(degreesToRadians(degreesPlus)) + width * cosf(degreesToRadians(degreesPlus))
t1 = CGAffineTransform(translationX: CGFloat(side1), y: CGFloat(side2))
}
t2 = t1!.rotated(by: CGFloat(degreesToRadians(Float(degrees))))
videoComposition = AVMutableVideoComposition()
videoComposition?.renderSize = CGSize(width: CGFloat(finalWidth), height: CGFloat(finalHeight))
videoComposition?.frameDuration = CMTimeMake(value: 1, timescale: 30)
instruction = AVMutableVideoCompositionInstruction()
instruction?.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: composition!.duration)
layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: (composition?.tracks[0])!)
layerInstruction?.setTransform(t2!, at: CMTime.zero)
instruction?.layerInstructions = NSArray(object: layerInstruction!) as! [AVVideoCompositionLayerInstruction]
videoComposition?.instructions = NSArray(object: instruction!) as! [AVVideoCompositionInstructionProtocol]
let playItem_ = AVPlayerItem(asset: composition!)
playItem_.videoComposition = videoComposition
var time: CMTime!
time = CMTime.zero
player.replaceCurrentItem(with: playItem_)
player.seek(to: time, toleranceBefore: CMTime.zero, toleranceAfter: CMTime.zero)
let exportSession = AVAssetExportSession(asset: composition!, presetName: AVAssetExportPresetMediumQuality)
exportSession?.outputURL = URL(string: String(format: "%@_rotated", url as CVarArg))
exportSession?.outputFileType = AVFileType.mov
exportSession?.videoComposition = videoComposition
exportSession?.shouldOptimizeForNetworkUse = true
exportSession?.timeRange = CMTimeRangeMake(start: CMTime.zero, duration: asset.duration)
exportSession?.exportAsynchronously(completionHandler: { () -> Void in
print("Video exported")
})
return player
}
func degreesToRadians(_ input: Float) -> Float {
let float: Float = 180
return Float(input) * .pi / float
}
func radiansToDegrees(_ input: Float) -> Float {
return Float(input) * 180 / .pi
}