草庐IT

ios - 插入耳机时奇怪的 AVMutableComposition 行为

coder 2023-09-11 原文

我有一个流式传输 mov 文件的应用程序。我的应用程序中的一项功能是在这些流式文件上录制音频。为了实现这一点,我在后台下载流文件,然后开始录音以捕获用户音频。用户完成后,我将录制的音频与我之前在后台下载的 mov 文件合并。

除插入耳机外,所有这些都运行良好。体验是一样的,但是当你去回放录音时,只捕获了音频。不知道为什么,mov 文件从未进入最终 Assets 。

这是我制作录音的方式:

let video = AVAsset(URL: currentCacheUrl)
let audioRecording = AVAsset(URL: currentRecordingUrl)

// 1 - Create AVMutableComposition object. This object will hold your AVMutableCompositionTrack instances.
let mixComposition = AVMutableComposition()

// 2 - Video track
let videoTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
do {
    try videoTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioRecording.duration),
                                   ofTrack: video.tracksWithMediaType(AVMediaTypeVideo)[0],
                                   atTime: kCMTimeZero)
} catch _ {
    print("Failed to load video track")
}

// 3 - Audio track
let audioTrack = mixComposition.addMutableTrackWithMediaType(AVMediaTypeAudio, preferredTrackID: 0)
do {
    try audioTrack.insertTimeRange(CMTimeRangeMake(kCMTimeZero, audioRecording.duration),
                                   ofTrack: audioRecording.tracksWithMediaType(AVMediaTypeAudio)[0],
                                   atTime: kCMTimeZero)
} catch _ {
    print("Failed to load audio track")
}

// 4 - Get path
let recordingsPath = MisueroKaraokeLatinoHelper.Variables.getRecordingsDirectory
let currentDate = NSDate()
let date = formatDate(currentDate)

let savePath = recordingsPath.URLByAppendingPathComponent("\(date).mov")

// 5 - Create Exporter
guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) else { return }
exporter.outputURL = savePath
exporter.outputFileType = AVFileTypeQuickTimeMovie
exporter.shouldOptimizeForNetworkUse = true

// 6 - Perform the Export
exporter.exportAsynchronouslyWithCompletionHandler() {
    dispatch_async(dispatch_get_main_queue()) { _ in
        print("save and merge complete")

        let recording = Recording(title: self.currentRecordSong.title, artist: self.currentRecordSong.artist, genre: self.currentRecordSong.genre, timestamp: currentDate, fileUrl: savePath)
        MisueroKaraokeLatinoHelper.Variables.Recordings.append(recording)
        MisueroKaraokeLatinoHelper.Variables.Recordings.sortInPlace({$0.timestamp.compare($1.timestamp) == NSComparisonResult.OrderedDescending})

        let recordingsData = NSKeyedArchiver.archivedDataWithRootObject(MisueroKaraokeLatinoHelper.Variables.Recordings)
        NSUserDefaults.standardUserDefaults().setObject(recordingsData, forKey: "Recordings")
    }
}

当 iOS 设备将其音频输出设置为蓝牙设备时,会发生类似的情况。最终录制捕获用户录制的音频和 mov 文件中的视频,但不捕获 mov 文件中的音频。给了什么?

最佳答案

addMutableTrackWithMediaType 添加指定媒体类型的轨道。通过在我添加视频轨道时指定 AVMediaTypeVideo 它只会添加视频轨道。因此,当没有插入耳机时,录音机会从正在播放的电影中拾取音频,但是,当插入耳机时,麦克风无法拾取通过耳塞播放的音频。

解决方案是将缓存的mov文件的音视频轨道都添加上,并处理所有轨道的滞后/同步。如果插入耳机或设备上的音频输出设置为蓝牙扬声器之类的设备,则还应有条件地添加缓存 mov 的音频,在这种情况下,录音机将无法清晰地拾取该音频。

接受其他解决方案/建议。但这种方法目前对我有用。

关于ios - 插入耳机时奇怪的 AVMutableComposition 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37661199/

有关ios - 插入耳机时奇怪的 AVMutableComposition 行为的更多相关文章

  1. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  2. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  3. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  4. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  5. ruby - Ruby gsub 替换中的行为不一致? - 2

    两个gsub产生不同的结果。谁能解释一下为什么?代码也可在https://gist.github.com/franklsf95/6c0f8938f28706b5644d获得.ver=9999str="\tCFBundleDevelopmentRegion\n\ten\n\tCFBundleVersion\n\t0.1.190\n\tAppID\n\t000000000000000"putsstr.gsub/(CFBundleVersion\n\t.*\.).*()/,"#{$1}#{ver}#{$2}"puts'--------'putsstr.gsub/(CFBundleVersio

  6. ruby-on-rails - Ruby 中意外的大小写行为 - 2

    我在一段非常简单的代码(如我所想)中得到了一个错误的值:org=4caseorgwhenorg=4val='H'endputsval=>nil请不要生气,我希望我错过了一些非常明显的东西,但我真的想不通。谢谢。 最佳答案 这是典型的Ruby错误。case有两种被调用的方法,一种是你传递一个东西作为分支的基础,另一种是你不传递的东西。如果您确实在case中指定了一个表达式语句然后评估所有其他条件并与===进行比较.在这种情况下org评估为false和org===false显然不是真的。所有其他情况也是如此,它们要么是真的,要么是假的。

  7. ruby - 使对象的行为类似于 ruby​​ 中并行分配的数组 - 2

    假设您在Ruby中执行此操作:ar=[1,2]x,y=ar然后,x==1和y==2。是否有一种方法可以在我自己的类中定义,从而产生相同的效果?例如rb=AllYourCode.newx,y=rb到目前为止,对于这样的赋值,我所能做的就是使x==rb和y=nil。Python有这样一个特性:>>>classFoo:...def__iter__(self):...returniter([1,2])...>>>x,y=Foo()>>>x1>>>y2 最佳答案 是的。定义#to_ary。这将使您的对象被视为要分配的数组。irb>o=Obje

  8. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  9. ruby - 了解在 Ruby 中与 lambda 一起使用的 inject 行为 - 2

    我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject

  10. ruby-on-rails - 浮点乘法的 Ruby 奇怪问题 - 2

    有没有人用ruby​​解决这个问题:假设我们有:a=8.1999999我们想将它四舍五入为2位小数,即8.20,然后乘以1,000,000得到8,200,000我们是这样做的;(a.round(2)*1000000).to_i但是我们得到的是8199999,为什么?奇怪的是,如果我们乘以1000、100000或10000000而不是1000000,我们会得到正确的结果。有人知道为什么吗?我们正在使用ruby​​1.9.2并尝试使用1.9.3。谢谢! 最佳答案 每当你在计算中得到时髦的数字时使用bigdecimalrequire'bi

随机推荐