ios - 使用 AVAssetReader 从 iPad 上的视频中读取帧时,图像方向不正确

标签 ios swift avfoundation avassetreader cmsamplebuffer

我首先要确定的几件事:

  • 这适用于多部 iPhone(iOS 10.3 和 11.x)
  • 这可以在任何 iPad 模拟器 (iOS 11.x) 上正常运行

我遇到的情况是,当我运行以下代码(从我的应用程序中浓缩以删除不相关的代码)时,我得到的图像是倒置的(横向)或旋转 90 度(纵向)。查看在此步骤之前处理的视频表明它的方向正确。所有测试均在 iOS 11.2.5 上完成。

* 已更新 *

我做了一些进一步的测试,发现了一些更有趣的项目:

  • 如果视频是从手机或外部来源导入的,则会进行适当处理
  • 如果视频是在 iPad 上以纵向录制的,那么读者将视频向左旋转 90 度提取
  • 如果视频是在 iPad 上横向录制的,那么读者会将其倒过来提取
  • 在上述两种情况下,UIImage 报告纵向方向

相关代码的精简版:

import UIKit
import AVFoundation

let asset = ...
let assetReader = try? AVAssetReader(asset: asset)

if let assetTrack = asset.tracks(withMediaType: .video).first,
    let assetReader = assetReader {
    let assetReaderOutputSettings = [
        kCVPixelBufferPixelFormatTypeKey as String : NSNumber(value: kCVPixelFormatType_32BGRA)
    ]
    let assetReaderOutput = AVAssetReaderTrackOutput(track: assetTrack,
                                                     outputSettings: assetReaderOutputSettings)
    assetReaderOutput.alwaysCopiesSampleData = false
    assetReader.add(assetReaderOutput)

    var images = [UIImage]()
    assetReader.startReading()

    var sample = assetReaderOutput.copyNextSampleBuffer()

    while (sample != nil) {
        if let image = sample?.uiImage { // The image is inverted here
            images.append(image)
            sample = assetReaderOutput.copyNextSampleBuffer()
        }
    }
    // Continue here with array of images...
}

最佳答案

经过一番探索,我发现了以下内容,使我能够从 AVAssetTrack 获取视频的方向:

let transform = assetTrack.preferredTransform
radians = atan2(transform.b, transform.a)

有了它之后,我就可以将它转换为度数:

let degrees = (radians * 180.0) / .pi

然后,使用 switch 语句我可以确定如何旋转图像:

Switch Int(degrees) {
   case -90, 90:
       // Rotate accordingly
   case 180:
       // Flip
   default:
       // Do nothing
}

关于ios - 使用 AVAssetReader 从 iPad 上的视频中读取帧时,图像方向不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48794195/

相关文章:

ios - 核心蓝牙读取数据

swift - 使用 UISwitch 设置初始化 Storyboard

ios - UIImages exported as movie 错误

c++ - OSX native API 视频解码 C++

ios - 以编程方式定义通知内容扩展的高度

IOS 在 View 之间切换

swift - 为什么我保存的用户数据无法快速正确加载?

swift - 如何在swift中将回调函数传递给另一个函数?

ios - AVCaptureVideoData输出分辨率

ios - 在 iOS 应用程序中跨多个 View Controller 共享某些数据的最佳方式是什么