2017-02-18 33 views
0

Привет, я пытаюсь понять, как реализовать цикл воспроизведения видео в GPUImage2, но пока не увенчался успехом. Класс MovieInput в GPUImage2 использует AVAssetReader для воспроизведения файлов фильмов, поэтому я исследовал способы петли AVAssetReader. Я нашел этот вопрос в StackOverFlow, посвященный этой теме. AVFoundation to reproduce a video loopКак получить AVAssetReader в цикл?

Лучший ответ был «AVAssetReader не поддерживает поиск или перезагрузки, это по существу последовательный декодер. Вы должны создать новый объект AVAssetReader читать одни и те же образцы снова.»

Я попытался выяснить, как подключить старый ресурсReader к новому, и я был не очень успешным, и он разбился каждый раз.

Мне было рекомендовано попробовать что-то вроде этого, но я не совсем уверен, как написать функцию generateAssetReader.

public func start() { 
    self.assetReader = generateAssetReader(asset: asset, readAudio: readAudio, videoOutputSettings: videoOutputSettings, audioOutputSettings: audioOutputSettings) 

asset.loadValuesAsynchronously(forKeys:["tracks"], completionHandler:{ 
      DispatchQueue.global(priority:DispatchQueue.GlobalQueuePriority.default).async(execute: { 
       guard (self.asset.statusOfValue(forKey: "tracks", error:nil) == .loaded) else { return } 

       guard self.assetReader.startReading() else { 
        print("Couldn't start reading") 
        return 
       } 

       var readerVideoTrackOutput:AVAssetReaderOutput? = nil; 

       for output in self.assetReader.outputs { 
        if(output.mediaType == AVMediaTypeVideo) { 
         readerVideoTrackOutput = output; 
        } 
       } 

       while (self.assetReader.status == .reading) { 
        self.readNextVideoFrame(from:readerVideoTrackOutput!) 
       } 


    if assetReader.status == .completed { 
     assetReader.cancelReading() 
     self.assetReader = nil 
     if self.loop { 
      self.start() 
     } else { 
      self.endProcessing() 
     } 
    } 
} 

У кого-нибудь есть ключ к решению этой проблемы с циклом? Это ссылка на весь код класса MovieInput. https://github.com/BradLarson/GPUImage2/blob/master/framework/Source/iOS/MovieInput.swift

+0

Какая ошибка? –

+0

Привет, спасибо за ответ. У меня есть рабочий цикл. Проблема в том, что я не уверен, как сделать ее бесконечной, и в текущем способе, которым я занимаюсь, проблема с памятью. Я в основном скопировал первую часть для запуска кода и поместил его в секцию цикла. Я также сделал новый актив. –

+0

Зацикливание вокруг него, похоже, не имело проблем с памятью, однако, когда я сделал функцию, чтобы сделать цикл и имел 20 Assetreaders. Цикл не работал так гладко. Как я могу создавать новые считыватели активов, когда они мне нужны, поэтому я не беру на себя лишний объем памяти и это бесконечный процесс? Должен ли я создать новый класс? –

ответ

0

Я нашел ответ на случай, если кто-то задается вопросом.

public func createReader() -> AVAssetReader 
{ 
    var assetRead:AVAssetReader! 
    do{ 
     assetRead = try AVAssetReader.init(asset: self.asset) 

     let outputSettings:[String:AnyObject] = [(kCVPixelBufferPixelFormatTypeKey as String):NSNumber(value:Int32(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange))] 
     let readerVideoTrackOutput = AVAssetReaderTrackOutput(track:self.asset.tracks(withMediaType: AVMediaTypeVideo)[0], outputSettings:outputSettings) 
     readerVideoTrackOutput.alwaysCopiesSampleData = false 

     assetRead.add(readerVideoTrackOutput) 
    }catch{ 

    } 

    return assetRead 
} 

public func start() { 
    self.assetReader = createReader() 
    asset.loadValuesAsynchronously(forKeys:["tracks"], completionHandler:{ 
     DispatchQueue.global(priority:DispatchQueue.GlobalQueuePriority.default).async(execute: { 
      guard (self.asset.statusOfValue(forKey: "tracks", error:nil) == .loaded) else { return } 

      guard self.assetReader.startReading() else { 
       print("Couldn't start reading") 
       return 
      } 

      var readerVideoTrackOutput:AVAssetReaderOutput? = nil; 

      for output in self.assetReader.outputs { 
       if(output.mediaType == AVMediaTypeVideo) { 
        readerVideoTrackOutput = output; 
       } 
      } 

      while (self.assetReader.status == .reading) { 
       self.readNextVideoFrame(from:readerVideoTrackOutput!) 
      } 

      if (self.assetReader.status == .completed) { 
       self.assetReader.cancelReading() 

       if (self.loop) { 
        // TODO: Restart movie processing 
        self.start() 
       } else { 
        self.endProcessing() 
       } 
      } 
     }) 
    }) 
}