标签: avassetwriter

iOS 更新录音开始后的录音时间的正确方法

如何使用 AVFoundation 中的捕获管道在录制过程中更新时间标签:

Mic -> AVCaptureDeviceInput -> AVCaptureSession -> AVCaptureAudioDataOutput
Run Code Online (Sandbox Code Playgroud)

AVCaptureAudioDataOutput 有 Delegate 和 AVAssetWritter 将sampleBuffers写入输出文件。在此解决方案中,我想更新录制时间。我可以记录用户点击“记录/暂停/恢复/停止”按钮时的时间,但是 Apple 是否有任何官方方法如何在开始时以 00:00:00 时间更新某些 UILabel。我知道我可以使用 NSTimer 但当我使用 AVAudioRecorder 时我有属性:

var currentTime: TimeInterval
// The time, in seconds, since the beginning of the recording.
Run Code Online (Sandbox Code Playgroud)

上述属性也适用于暂停/继续按钮。

现在,在这个新管道中,我没有这个属性,我想知道我是否丢失了某些东西并且无法在任何地方找到它。我还注意到 AVCaptureSession 有名为 masterClock 的 CMClock 属性,但自记录开始以来我不确定如何使用它来计算时间。

我不明白时钟和方法的全部概念,例如:

CMClockGetHostTimeClock()
CMSyncConvertTime
Run Code Online (Sandbox Code Playgroud)

如何在基于sampleBuffer的AVCaptureAudioDataOutputSampleBufferDelegate方法中获取自录音开始以来的秒数?

更新

我发现了一个名为 CMTimebase 的类,我认为这正是我正在寻找的。目前我不知道如何使用它,但我在操场上进行了一些实验后发现了这一点。

import CoreMedia

let masterClock = CMClockGetHostTimeClock() // This masterclock should be from captureSession
var timebase: CMTimebase? = nil
CMTimebaseCreateWithMasterClock(kCFAllocatorDefault, masterClock, &timebase)

print(CMTimeGetSeconds(CMTimebaseGetTime(timebase!)))

CMTimebaseSetRate(timebase!, 1.0) // …
Run Code Online (Sandbox Code Playgroud)

iphone avfoundation ios avcapturesession avassetwriter

5
推荐指数
1
解决办法
2016
查看次数

在 iOS 上使用 HEVC 编码器输出视频尺寸巨大

我有一个项目,目前使用 H.264 编码器在 iOS 上录制视频。我想尝试在 iOS 11 中使用新的 HEVC 编码器来减小文件大小,但发现使用 HEVC 编码器会导致文件大小急剧膨胀。 GitHub 上的一个项目显示了该问题 - 它使用 H.264 和 H.265 (HEVC) 编码器同时将相机中的帧写入文件,并将生成的文件大小打印到控制台。

AVFoundation 类的设置如下:

class VideoWriter {
    var avAssetWriterInput: AVAssetWriterInput
    var avAssetWriter: AVassetWriter
    init() {
        if #available(iOS 11.0, *) {
            avAssetWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: [AVVideoCodecKey:AVVideoCodecType.hevc, AVVideoHeightKey:720, AVVideoWidthKey:1280])
        }
        avAssetWriterInput.expectsMediaDataInRealTime = true
        do {
            let url = directory.appendingPathComponent(UUID.init().uuidString.appending(".hevc"))
            avAssetWriter = try AVAssetWriter(url: url, fileType: AVFileType.mp4)
            avAssetWriter.add(avAssetWriterInput)
            avAssetWriter.movieFragmentInterval = kCMTimeInvalid
        } catch {
            fatalError("Could not initialize AVAssetWriter \(error)")
        }
    }
...
Run Code Online (Sandbox Code Playgroud)

然后框架是这样写的: …

avfoundation ios avassetwriter hevc swift

5
推荐指数
1
解决办法
4688
查看次数

如何设置 AVAssetWriterInput 的预期帧率

我有一个应用程序,它以不同的方式对视频进行编码并将其保存到照片库 - 它可以剪切特定的时间范围,添加图片、文本等。一切都运行良好,直到我尝试对视频进行 120+ fps 的编码。问题是视频似乎是慢动作,而我根本不追求这个目标。

在这里,我发现了有关AVAssetWritterInput名为 的属性AVVideoExpectedSourceFrameRateKey,但问题是当我尝试将此参数应用于我的 时AVAssetWritterInput,我收到此错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[AVAssetWriterInput initWithMediaType:outputSettings:sourceFormatHint:] Output settings dictionary contains one or more invalid keys: ExpectedFrameRate'

这是我的AVAssetWriterInput初始化,一点也不花哨:

let input = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: [AVVideoCodecKey: AVVideoCodecJPEG,
                                                                                         AVVideoHeightKey: correctedContentSize.height,
                                                                                         AVVideoWidthKey: correctedContentSize.width,
                                                                                         AVVideoExpectedSourceFrameRateKey: 60])
Run Code Online (Sandbox Code Playgroud)

任何帮助,将不胜感激。谢谢。

video frame-rate ios avassetwriter avassetwriterinput

5
推荐指数
1
解决办法
945
查看次数

从 SCNView 录制视频的最快方法

我有 SCNView,屏幕中间有一些对象,用户可以旋转它、缩放等。

我想在视频中记录所有这些动作并实时添加一些声音。另外,我只想记录SCNView的中间部分(例如SCNView框架是375x812,但我只想中间375x375,没有顶部和底部边框)。我还想在视频捕获的同时将其显示在屏幕上。

我当前的变体是:

func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {
    DispatchQueue.main.async {
        if let metalLayer = self.sceneView.layer as? CAMetalLayer, let texture = metalLayer.currentSceneDrawable?.texture, let pixelBufferPool = self.pixelBufferPool {
            //1
            var maybePixelBuffer: CVPixelBuffer? = nil
            let status  = CVPixelBufferPoolCreatePixelBuffer(nil, pixelBufferPool, &maybePixelBuffer)

            guard let pixelBuffer = maybePixelBuffer else { return }

            CVPixelBufferLockBaseAddress(pixelBuffer, [])

            let bytesPerRow = CVPixelBufferGetBytesPerRow(pixelBuffer)
            let region = MTLRegionMake2D(Int(self.fieldOfView.origin.x * UIScreen.main.scale),
                                         Int(self.fieldOfView.origin.y * UIScreen.main.scale),
                                         Int(self.fieldOfView.width * UIScreen.main.scale),
                                         Int(self.fieldOfView.height * UIScreen.main.scale))

            let pixelBufferBytes = CVPixelBufferGetBaseAddress(pixelBuffer)!
            texture.getBytes(pixelBufferBytes, …
Run Code Online (Sandbox Code Playgroud)

ios avassetwriter scenekit metal cvpixelbuffer

5
推荐指数
1
解决办法
1069
查看次数

如何使用 AVAssetWriter 将 colorProfile 添加到使用 CGDisplayStream 从屏幕录制的视频中

我编写了一个屏幕录制应用程序,它使用 VideoToolbox 和 AVWriter 写出 H.264 电影文件。与原始屏幕相比,录制文件中的颜色有点暗淡。我知道这是因为 colorProfile 未存储在视频文件中。

这与如何对 AVAssetWriter 输出进行颜色管理密切相关

我创建了一个测试台来在 github ScreenRecordTest上展示这一点

如果您运行此应用程序,您可以使用 CMD-R 开始录制并使用相同的 CMD-R 停止录制(您必须开始和停止录制一次才能获得完整写入的电影文件)。您将在 /tmp/ 文件夹中找到类似以下名称的录音:“/tmp/grab-2018-10-25 09:23:32 +0000.mov”

录制时,应用程序会显示两个实时图像:a)从 CGDisplayStream 获取的帧 - 和 - b)来自压缩器的 cmSampleBuffer。

我发现从 CGDisplayStream 返回的 IOSurface 没有进行颜色管理,因此您会注意到压缩之前已经出现“暗淡”颜色。如果您取消 AppDelegate.swift 中第 89 行的注释

// cgImage = cgImage.copy(colorSpace: screenColorSpace)!
Run Code Online (Sandbox Code Playgroud)

此实时预览将具有正确的颜色。现在这仅用于显示压缩前的 IOSurface。我不知道如何使其他实时预览(压缩后)(AppDelegate 中的第 69 行)显示正确的颜色(例如:如何将 colorProfile 应用于 CMSampleBuffer),或者最重要的是如何使用正确的配置文件,以便在打开 .mov 文件时我在播放时获得正确的颜色。

macos avfoundation avassetwriter video-toolbox

5
推荐指数
0
解决办法
315
查看次数

Swift:使用 AVAssetExportSession() 连续合并视频

我有一组存储为 AVURLAsset 的视频录制,我想将视频合并到 1 个剪辑中,以便它们连续播放,视频之间没有时间间隔。下面是我希望做的,但它只显示第一个视频。注意:我希望视频连续播放,并且每个视频之间没有空白。例如,如果当手机未录音时,录音 1 和录音 2 之间存在实时时间,则输出不应显示此情况。

感谢您的帮助!

func mergeVideos(handler: @escaping (_ asset: AVAssetExportSession)->()) {
    let mixComposition = AVMutableComposition()
    var videoTime = CMTime.zero
    for video in self.recordings {

        let tracks = video.tracks(withMediaType: .video)
        let videoTrack = tracks[0]
        let videoTimeRange = CMTimeRangeMake(start: .zero, duration: video.duration)
        guard let compositionVideoTrack: AVMutableCompositionTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else { return }
        do {
            try compositionVideoTrack.insertTimeRange(videoTimeRange, of: videoTrack, at: videoTime)
            videoTime = CMTimeAdd(videoTime, video.duration)
        } catch {
            print("An error occurred")
            return
        }
    } …
Run Code Online (Sandbox Code Playgroud)

xcode video-processing avassetwriter avassetexportsession swift

5
推荐指数
1
解决办法
1540
查看次数

AVAssetWriterInput H.264 Passthrough to QuickTime(.mov) - 通过SPS/PPS创建avcC原子?

我有一个H.264/AVC NAL流,包括类型1(P帧),5(I帧),7(SPS)和8(PPS).我想将它们写入.mov文件而不重新编码.我试图用AVAssetWriter这个来做.AVAssetWriterInput各州的文件:

为outputSettings传递nil指示输入传递附加的样本,在将它们写入输出文件之前不进行任何处理.例如,如果要附加已经采用所需压缩格式的缓冲区,则此方法很有用.但是,只有在写入QuickTime Movie文件时才支持passthrough(即AVAssetWriter是使用AVFileTypeQuickTimeMovie初始化的).对于其他文件类型,您必须指定非零输出设置.

我正在尝试从这些NAL中创建CMSampleBuffers并将它们附加到资产编写器输入,但我无法以产生格式良好的.mov文件的方式输入数据,我无法在任何地方找到任何线索关于如何做到这一点.

到目前为止,我得到的最好结果是以附件B字节流格式传递NAL(按照顺序7 8 5 1 1 1 ....重复)并在VLC中播放结果.因此,我知道NAL包含有效数据,但由于.mov文件没有avcC原子且mdat原子填充了附件B字节流,因此QuickTime不会播放视频.

现在我试图用4字节(由lengthSizeMinusOne字段指定)长度字段而不是附件B分隔符传入NAL,就我所知,它们应该被打包到mdat原子中. .

我不知道如何让资产作者写一个avcC原子.我附加的每个样本都被推入mdat原子.

有谁知道如何将原始H.264数据传递到为传递(nil outputSettings)配置的AVAssetWriterInput并让它生成正确形成的QuickTime文件?

iphone avfoundation h.264 ios avassetwriter

4
推荐指数
1
解决办法
2680
查看次数

使用AVAssetWriter录制无间隙音频

我正在尝试记录音频片段并重新组合它们而不会产生音频差距.

最终的目标是也有视频,但我发现音频本身在结合时会产生差距 ffmpeg -f concat -i list.txt -c copy out.mp4

如果我把音频放在HLS播放列表中,也有间隙,所以我不认为这是ffmpeg独有的.

这个想法是样本连续进入,我的控制器将样本路由到正确的样本AVAssetWriter.如何消除音频中的差距?

import Foundation
import UIKit
import AVFoundation

class StreamController: UIViewController, AVCaptureAudioDataOutputSampleBufferDelegate, AVCaptureVideoDataOutputSampleBufferDelegate {
    var closingAudioInput: AVAssetWriterInput?
    var closingAssetWriter: AVAssetWriter?

    var currentAudioInput: AVAssetWriterInput?
    var currentAssetWriter: AVAssetWriter?

    var nextAudioInput: AVAssetWriterInput?
    var nextAssetWriter: AVAssetWriter?

    var videoHelper: VideoHelper?

    var startTime: NSTimeInterval = 0
    let closeAssetQueue: dispatch_queue_t = dispatch_queue_create("closeAssetQueue", nil);

    override func viewDidLoad() {
        super.viewDidLoad()
        startTime = NSDate().timeIntervalSince1970
        createSegmentWriter()
        videoHelper = VideoHelper()
        videoHelper!.delegate = self
        videoHelper!.startSession()
        NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "createSegmentWriter", userInfo: …
Run Code Online (Sandbox Code Playgroud)

avfoundation ios avassetwriter swift

4
推荐指数
1
解决办法
1252
查看次数

CMSampleBuffer 的样本呈现时间代表什么?

我们的应用程序使用 AVFoundation 来捕获视频、显示、操作和使用其示例缓冲区导出视频。我试图了解CMSampleBufferGetPresentationTimeStamp(_:)CMTime 实际代表什么。

例如,视频采集开始时,第一个样本的呈现时间为 93 小时 5 分钟。我不明白这个价值从何而来。使用第一个示例的演示时间来启动 AVAssetWriter 会话会在视频播放开始之前创建 93 小时的黑帧。

avfoundation ios avassetwriter swift

4
推荐指数
1
解决办法
846
查看次数

超过 2 个通道的 AVAssetWriterInput

有人知道如何使用具有 2 个以上通道的 AVAssetWriterInput init 吗?

我正在尝试初始化一个音频输入,以这种方式在 AVAssetWriter 之后添加它:

let audioInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: audioOutputSettings)
Run Code Online (Sandbox Code Playgroud)

assetWriter.add(audioInput)

assetWriter.startWriting()

但是当我使用包含大于 2 的通道键数的 audioOutputSettings 字典初始化 audioInput 时它会崩溃。错误是:

Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ’*** -[AVAssetWriterInput initWithMediaType:outputSettings:sourceFormatHint:] 6 is not a valid channel count for Format ID ‘aac ’. Use kAudioFormatProperty_AvailableEncodeNumberChannels (<AudioToolbox/AudioFormat.h>) to enumerate available channel counts for a given format.

avfoundation ios avassetwriter avassetexportsession swift

4
推荐指数
1
解决办法
1700
查看次数