Page 1 of 1

MobileVLCKit 3.0 not getting all events...

Posted: 09 Sep 2018 21:51
by Mavro
Things like VLCMediaPlayerState switch from 7 to 2 (buffering) and 0 stopped... but never get playing.

When you turn on logging -- you can see that VLC is switching to "play" but the event never makes it to MobileVLCKit.

Also, not getting any of the dialogs which is fine... but also not getting any of the events like 401, etc. either.

Is this a known bug?

How can we fix it?

Compiling 3.1.4 to see if that fixes these issues... was running 3.0.

Re: MobileVLCKit 3.0 not getting all events...

Posted: 20 Sep 2018 16:36
by fkuehne
This is a known issue in VLCKit. It will be solved by a re-write of the event manager, which is complex and not scheduled for this year.

Re: MobileVLCKit 3.0 not getting all events...

Posted: 18 Sep 2021 11:56
by shaybc
i rely on: Stream Added event

Code: Select all

... private var playerStateChangedNotification: NSObjectProtocol? override init(frame: CGRect) { super.init(frame: frame) mediaPlayer.media = VLCMedia(url: URL(string: "http://some.video.URL")!) mediaPlayer.delegate = self mediaPlayer.drawable = self playerStateChangedNotification = NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: VLCMediaPlayerStateChanged), object: mediaPlayer, queue: nil, using: self.playerStateChanged) mediaPlayer.play() } func playerStateChanged(_ notification: Notification) { if(mediaPlayer.state == VLCMediaPlayerState.esAdded) { ...Do you Stuff here... } }


you could also do a work around and instead of immediately call to play action (mediaPlayer.play()) you could call play, pause, delayed play (0.5 sec delay or even 0.3 sec delay), the effect is barely noticeable:


Code: Select all

override init(frame: CGRect) { super.init(frame: frame) mediaPlayer.media = VLCMedia(url: URL(string: "http://some.video.URL")!) mediaPlayer.delegate = self mediaPlayer.drawable = self playerStateChangedNotification = NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: VLCMediaPlayerStateChanged), object: mediaPlayer, queue: nil, using: self.playerStateChanged) mediaPlayer.play() mediaPlayer.pause() DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [unowned self] in self.mediaPlayer.play() } } func playerStateChanged(_ notification: Notification) { if(mediaPlayer.state == VLCMediaPlayerState.playing) { ...Do you Stuff here... } } ...

and lastly you could use a simple flag:

Code: Select all

... private var isFirstPlay: Bool = true // this trick is to overcome VLC bug that first play event never received override init(frame: CGRect) { super.init(frame: frame) mediaPlayer.media = VLCMedia(url: URL(string: "http://some.video.URL")!) mediaPlayer.delegate = self mediaPlayer.drawable = self playerStateChangedNotification = NotificationCenter.default.addObserver(forName: Notification.Name(rawValue: VLCMediaPlayerStateChanged), object: mediaPlayer, queue: nil, using: self.playerStateChanged) mediaPlayer.play() } func playerStateChanged(_ notification: Notification) { if(mediaPlayer.state == VLCMediaPlayerState.buffering && isFirstPlay) { isFirstPlay = false ...Do you Stuff here... } } ...


side not: do not forger to call unregister to the NotificationCenter Observer before deleting the player var (do not rely on the deinit - do it before deinit is called, otherwise the player is never released and a memory leak will occur)

i add these functions:


Code: Select all

... func unregisterObservers() { NotificationCenter.default.removeObserver(playerStateChangedNotification as Any) } deinit { print("deinit()") } public func stopPlayer() { print("stopPlayer()") mediaPlayer.stop() unregisterObservers() } ...