Closed alexrmacleod closed 8 years ago
Cool, thanks for your contribution! I'll have a look later and see how I can integrate that into the main project.
@teodorpatras if you do decide to add it, I would really appreciate it if you let me know here... so I can update my app to your new logic. btw http://soundradio.hk/holding-page/ some songs on the constant stream don't seem to have any titlemeta data. would be great if you could accommodate for this with a notitle setting.
new version released, thanks a lot for your input
@teodorpatras Awesome! how would I use this new feature? how to get to the time metadata?
implement func jukeboxDidUpdateMetadata(jukebox : Jukebox, forItem: JukeboxItem)
and then you can access item.meta
💯 thx!
@teodorpatras How would I check if jukebox stopped playing when I turn on airport mode in control center and killing the internet connection? I was previously doing this (in the jukebox object) by running if change!["new"]!.isKindOfClass(NSNull)
(which gets run when there is no internet connection) in the observeValueForKeyPath
and then setting the jukebox to self.state = .Failed
. then in my Viewcontroller using the jukeboxStateDidChange
delegate method I would update my view items accordingly. example below from my project.
Am I doing this wrong? currently in the new 0.1.3 jukebox update I don't know how to tell my view controller the music has stopped playing when I kill the internet connection via control center with airport mode turned on! any ideas?
`
private func registerForPlayToEndNotification(withItem item: AVPlayerItem) {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "playerItemDidPlayToEnd:", name: AVPlayerItemDidPlayToEndTimeNotification, object: item)
item.addObserver(self, forKeyPath: "timedMetadata", options: NSKeyValueObservingOptions.New, context: nil)
}
private func unregisterForPlayToEndNotification(withItem item : AVPlayerItem) {
NSNotificationCenter.defaultCenter().removeObserver(self, name: AVPlayerItemDidPlayToEndTimeNotification, object: item)
item.removeObserver(self, forKeyPath: "timedMetadata", context: nil)
}
override public func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
print("keyPath: \(keyPath)")
if keyPath == "timedMetadata" {
let playerItem = object as? AVPlayerItem
if playerItem?.timedMetadata != nil {
print("playerItem: \(playerItem)")
print("playerItem?.timedMetadata: \(playerItem?.timedMetadata)")
for metadata in playerItem!.timedMetadata! as [AVMetadataItem] {
print("metadata: \(metadata)")
let info = String(format: "%@", metadata.stringValue!)
// let title = "\(info) ~ "
let infoArray = info.characters.split{$0 == " "}.map(String.init)
let parsedArray = removeDuplicates(infoArray)
print("parsedArray: \(parsedArray)")
var title:String = ""
// for i in 0...parsedArray.count {
// title.append(parsedArray[i])
// }
for parsedInfo in parsedArray {
print("parsedInfo:!!!! \(parsedInfo)")
// title + parsedInfo
title.addString("\(parsedInfo) ")
}
print("title:!!!! \(title)")
// or simply:
// let fullNameArr = fullName.characters.split{" "}.map(String.init)
// print("infoArray: \(infoArray)")
// var i = 0
// for info in infoArray {
// i += 1
// if info.containsString("-") {
//
// print("##########: \(info)")
// }
// }
// infoArray[0] // First
// infoArray[1] // Last
currentItem?.title = title
currentItem?.artwork = UIImage(named: "album-art")
if !info.isEmpty {
updateInfoCenter()
}
print("Now Playing: \(info)")
}
}
//Checking if internet connection has canceled
if change!["new"]!.isKindOfClass(NSNull) {
print("isKindOfClass")
queuedItems.removeAll()
self.state = .Failed
}
print("object: \(object)")
print("change: \(change)")
print("context: \(context)")
}
}
`
This is a sensible issue because if an item fails loading this might be due to several reasons, and there's no point in removing all items from the playlist and setting the status to .Failed. Right now the status remains on .Loading
if it cannot fetch the data and if you turn the airplane mode off and loop through the songs list, it should automatically reload them.
That's strange because before I came up with the above solution I was watching jukeboxStateDidChange hoping for a state change when I turn on airport mode. However when I turn Airport mode on the jukebox state did NOT change. let alone change to .Loading. Can you please confirm that the jukebox status does change to jukebox.state == .Loading
when airport mode is switched on?
My situation is a follows. I have an animation image loop that needs to be stopped when the internet connection is stopped (when the music stops streaming). How could I achieve this best with your framework?
Here is how I start the jukebox item
`
jukebox = Jukebox(
delegate: self,
items: [
JukeboxItem(
URL: NSURL(string: "http://soundradio.hk/sound-radio.m3u")!),
])
print("jukebox.currentItem?.title: \(jukebox.currentItem?.title)")
print("jukebox.currentItem?.playerItem: \(jukebox.currentItem?.playerItem)")
//Play music when app opens
jukebox.play()
`
@teodorpatras ???
atm, when the loading fails, the status does not update, can you open an issue for that? and I'll take care of it when I get the time, right now I don't have so much time to spare
@teodorpatras Loving jukebox - found a hacky solution to getting title metadata from a http://soundradio.hk/sound-radio.m3u stream.
I use item.addObserver inside the registerForPlayToEndNotification() to listen for "timedMetadata". Then at the bottom of the observeValueForKeyPath() I call updateInfoCenter() and add the new title to the currentItem, (had to change the properties from private to public)
`
`
Then at the bottom of the updateInfoCenter() (look below) I call a new protocol method self.delegate!.jukeboxMetadataDidUpdate(item) so I can update UILabels and UITextViews in any viewcontroller with the new title!
`
`
Just letting you know... maybe theres a way you can integrate this into jukeBox in a less hacky fashion. Since you know jukeBox very well.