2017-03-18 63 views
1

我有有一個視頻在它玩tvOS應用。 基本上有兩種視頻(同一視頻的不同速度的版本)。一個是12MB大小,另一個是1.9MB。tvOS應用程序內存問題:如何解決它?

當應用程序啓動時,它運行良好(Xcode中示出了191MB)。但是,當點擊正常速度按鈕一次,內存就會達到350MB。當我分別點擊普通按鈕和快速按鈕時,這種情況會持續增加,並且一度變爲1GB +。你可以看到附件。當視頻結束並且應用程序停止時,它甚至達到了3GB。 enter image description here

有沒有辦法從停止解決內存問題並保存應用程序?

的另一個問題是:當蘋果電視,我們去到另一個應用程序從這個程序,並回來,視頻再次停止。但是,在模擬器中,它不會發生。有人可以幫我解決這兩個問題嗎?

這裏是我使用的代碼:

var avPlayerLayer: AVPlayerLayer! 
var paused: Bool = false 

func playmyVideo(myString: String) { 

    let bundle: Bundle = Bundle.main 
    let videoPlayer: String = bundle.path(forResource: myString, ofType: "mov")! 
    let movieUrl : NSURL = NSURL.fileURL(withPath: videoPlayer) as NSURL 

    print(movieUrl) 

    viewVideo.playVideoWithURL(url: movieUrl) 


} 
@IBAction func normalPressed(_ sender: Any) { 

    playmyVideo(myString: "normal") 


} 


@IBAction func forwardPressed(_ sender: Any) { 

    playmyVideo(myString: "fast") 

} 

class VideoPlay: UIView { 


private var player : AVPlayer! 

private var playerLayer : AVPlayerLayer! 

init() { 

    super.init(frame: CGRect.zero) 
    self.initializePlayerLayer() 

} 

override init(frame: CGRect) { 
    super.init(frame: frame) 
    self.initializePlayerLayer() 
    self.autoresizesSubviews = false 
} 

required init?(coder aDecoder: NSCoder) { 
    super.init(coder: aDecoder) 
    self.initializePlayerLayer() 

} 



private func initializePlayerLayer() { 

    playerLayer = AVPlayerLayer() 
    playerLayer.backgroundColor = UIColor.clear.cgColor 



    playerLayer.videoGravity = AVLayerVideoGravityResizeAspectFill 


    self.layer.addSublayer(playerLayer) 

    playerLayer.frame = UIScreen.main.bounds 


} 

func playVideoWithURL(url: NSURL) { 

    player = AVPlayer(url: url as URL) 
    player.isMuted = false 

    playerLayer.player = player 

    player.play() 

    loopVideo(videoPlayer: player) 
} 

func toggleMute() { 
    player.isMuted = !player.isMuted 
} 

func isMuted() -> Bool 
{ 
    return player.isMuted 
} 

func loopVideo(videoPlayer: AVPlayer) { 

    NotificationCenter.default.addObserver(forName: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: nil, queue: nil) { notification in 
     let t1 = CMTimeMake(5, 100); 
     self.player.seek(to: t1) 
     videoPlayer.seek(to: kCMTimeZero) 
     self.player.play() 
    } 
} 

} 
+0

和一些代碼你在用什麼? –

+0

@SamuelTulach嗨。我已經包含了我們正在使用的代碼 – BizDev

+0

@SamuelTulach HI。請檢查我的代碼... – BizDev

回答

1

我看到你的代碼的兩個問題:

  1. 每次playVideoWithURL方法被調用,你創建的,而不是已經重用新AVPlayer例如,現有的。當你要玩另一個URL你可以叫你的player財產replaceCurrentItem(with:)方法。

這本身是有點低效率的,但應該不會造成你所說的內存問題。我認爲原因是:

  1. 每次調用loopVideo方法時,都會傳遞一個閉包給NotificationCenter.default.addObserver。此封閉對videoPlayer產生了強烈的參考。你永遠不會從通知中心刪除觀察者。

由於loopVideo在每次創建新AVPlayer實例時調用,這些實例都永遠不會釋放,從而導致您所描述的內存問題。

要解決它,你可以:

  • 初始化player酒店只有playVideoWithURL一次,然後用replaceCurrentItem當你要玩另一個視頻
  • 也改變了「循環」的邏輯,讓你打電話NotificationCenter.default.addObserver只有一次
  • 您傳遞給NotificationCenter.default.addObserver的關閉會造成內存泄漏(請參閱this question)。您可以通過捕獲self弱擺脫它:

    NotificationCenter.default.addObserver(forName:
    NSNotification.Name.AVPlayerItemDidPlayToEndTime,object: nil, queue: nil) { [weak self], notification in

    self?.player.seek(to: kCMTimeZero) 
        self?.player.play() 
    

    }

還記得打電話removeObserverVideoPlay類的deinit方法。