2016-09-22 5 views
0

Я пытаюсь настроить собственное сжатие видео в swift, основанном на этом сообщении SO, которое вместо этого использовало Obj-C (How can I reduce the file size of a video created with UIImagePickerController?). Тем не менее, у меня есть несколько проблем, которые преобразуют синтаксис, в частности, ошибку, выше которой выделяется через словарь. Функция сжатия ниже:Значение типа DictionaryLiteral <_,_> не соответствует «Any» в режиме слияния

func convertVideoToLowQuailty(withInputURL inputURL: URL, outputURL: URL) { 
    //setup video writer 
    var videoAsset = AVURLAsset(url: inputURL, options: nil) 
    var videoTrack = videoAsset.tracks(withMediaType: AVMediaTypeVideo)[0] 
    var videoSize = videoTrack.naturalSize 
    var videoWriterCompressionSettings = [ 
     AVVideoAverageBitRateKey : Int(1250000) 
    ] 

    var videoWriterSettings : NSDictionary = [ 
     DictionaryLiteral : (Key: AVVideoCodecKey, Object: AVVideoCodecH264), 
     AVVideoCompressionPropertiesKey : videoWriterCompressionSettings, 
     AVVideoWidthKey : Int(videoSize.width), 
     AVVideoHeightKey : Int(videoSize.height) 
    ] 

    var videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoWriterSettings as! [String : Any?]) 
    videoWriterInput.expectsMediaDataInRealTime = true 
    videoWriterInput.transform = videoTrack.preferredTransform 
    var videoWriter = try! AVAssetWriter(outputURL: outputURL, fileType: AVFileTypeMPEG4) 
    videoWriter.add(videoWriterInput) 
    //setup video reader 
    var videoReaderSettings = [ (kCVPixelBufferPixelFormatTypeKey as String) : Int(kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange) ] 
    var videoReaderOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings) 
    var videoReader = try! AVAssetReader(asset: videoAsset) 
    videoReader.add(videoReaderOutput) 
    //setup audio writer 
    var audioWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeAudio, outputSettings: nil) 
    audioWriterInput.expectsMediaDataInRealTime = false 
    videoWriter.add(audioWriterInput) 
    //setup audio reader 
    var audioTrack = videoAsset.tracks(withMediaType: AVMediaTypeAudio)[0] 
    var audioReaderOutput = AVAssetReaderTrackOutput(track: audioTrack, outputSettings: nil) 
    var audioReader = try! AVAssetReader(asset: videoAsset) 
    audioReader.add(audioReaderOutput) 
    videoWriter.startWriting() 
    //start writing from video reader 
    videoReader.startReading() 
    videoWriter.startSession(atSourceTime: kCMTimeZero) 
    var processingQueue = DispatchQueue(label: "processingQueue1") 
    videoWriterInput.requestMediaDataWhenReady(on: processingQueue, using: {() -> Void in 
     while videoWriterInput.isReadyForMoreMediaData { 
      var sampleBuffer: CMSampleBuffer 
      if videoReader.status == .reading && (sampleBuffer == videoReaderOutput.copyNextSampleBuffer()!) { 
       videoWriterInput.append(sampleBuffer) 

      } 
      else { 
       videoWriterInput.markAsFinished() 
       if videoReader.status == .completed { 
        //start writing from audio reader 
        audioReader.startReading() 
        videoWriter.startSession(atSourceTime: kCMTimeZero) 
        var processingQueue = DispatchQueue(label: "processingQueue2") 
        audioWriterInput.requestMediaDataWhenReady(on: processingQueue, using: {() -> Void in 
         while audioWriterInput.isReadyForMoreMediaData { 
          var sampleBuffer: CMSampleBuffer 
          if audioReader.status == .reading && (sampleBuffer == (audioReaderOutput.copyNextSampleBuffer()!)) { 
           audioWriterInput.append(sampleBuffer) 
          } 
          else { 
           audioWriterInput.markAsFinished() 
           if audioReader.status == .completed { 
            videoWriter.finishWriting(completionHandler: {() -> Void in 
             self.sendMovieFile(at: outputURL) 
            }) 
           } 
          } 
         } 
        }) 
       } 
      } 

     } 
    }) 
} 
+0

изменить ваши videoWriterSettings заявление в 'вар videoWriterSettings: [String: Любой]' –

+0

@LeoDabus же ошибка все еще присутствует –

+0

'вар videoWriterSettings: [String: Любой] = [AVVideoCodecKey: AVVideoCodecH264, AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey: NSNumber (значение: 1250000)], AVVideoWidthKey: videoSize.width в NSNumber, AVVideoHeightKey: videoSize.height в NSNumber] ' –

ответ

0

Я не понимаю, почему вам нужна эта строка:

DictionaryLiteral : (Key: AVVideoCodecKey, Object: AVVideoCodecH264), 

Проводов связанной нити, вы можете написать что-то вроде этого:

var videoWriterCompressionSettings: [String: AnyObject] = [ 
     AVVideoAverageBitRateKey : 1250000 as NSNumber 
    ] 

    var videoWriterSettings : [String: AnyObject] = [ 
     AVVideoCodecKey: AVVideoCodecH264 as NSString, 
     AVVideoCompressionPropertiesKey : videoWriterCompressionSettings as NSDictionary, 
     AVVideoWidthKey : videoSize.width as NSNumber, 
     AVVideoHeightKey : videoSize.height as NSNumber 
    ] 

    var videoWriterInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: videoWriterSettings) 

(Кто-то предпочитает [String: Any], чем [String: AnyObject], говоря, что это более Swifty в Swift 3. С помощью Any вы можете удалить некоторые отливки, но можете mistaki ndly содержат некоторые плохие вещи, которые будут обнаружены только во время выполнения.)

И еще одна очень плохая часть вашего кода - as! [String : Any?]. Вы должны пройти [String: Any]? до AVAssetWriterInput.init(mediaType:outputSettings:), а не [String: Any?].

(Там могут быть некоторые другие плохие части, которые я не проверил ...)

+0

Хорошо, спасибо очень, я проверю это и, надеюсь, все исправления, я использовал конвертер Obj-C, чтобы это сделать, поскольку я не понимаю Obj-C –

+0

@ j.doe, я вижу. Иногда такие инструменты (включая Swift migrator) генерируют странные выходы. Надеюсь, вы скоро исправите все ваши проблемы. – OOPer