从M3U8流视频获取Swift ios 8中的定时元数据

Jac*_*rks 5 metadata mpmovieplayercontroller swift ios8

我想在swift中复制这个https://jmacmullin.wordpress.com/2010/11/03/adding-meta-data-to-video-in-ios/.

这是杰克的代码在行动中的视频......

目标C HLS流中的定时Metadat

这是类似的东西的附加链接......

http://cloudfields.net/blog/metadata-audiostream-mp​​movieplayercontroller/

当我的视频正在播放定时元数据时,应该更新按钮以在单击时重定向到webview中的特定youtube网址.我的视频大约15分钟,有6个定时元数据网址.

我无法在Swift中找到任何关于如何实现此目的的代码或文档.我已经设法将Jake的Objective C代码转换为他的Notification调用.

// Register for meta-data notifications
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
 [center addObserver:self
       selector:@selector(metadataUpdate:)
           name:MPMoviePlayerTimedMetadataUpdatedNotification
         object:nil];
Run Code Online (Sandbox Code Playgroud)

到Swift Code

       NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: "metadataUpdated",
            name: MPMoviePlayerTimedMetadataUpdatedNotification,
            object: nil)
Run Code Online (Sandbox Code Playgroud)

杰克的功能

Actor *actor = [[Actor alloc] init];

 if ([player timedMetadata]!=nil && [[player timedMetadata] count] > 0) {
for (MPTimedMetadata *metadata in [player timedMetadata]) {
if ([[metadata.allMetadata valueForKey:@"key"] isEqualToString:@"TPE1"]) {
        [actor setName:[metadata.allMetadata objectForKey:@"value"]];
    }
    if ([[metadata.allMetadata valueForKey:@"key"] isEqualToString:@"WXXX"]) {
        NSURL *url = [NSURL URLWithString:[metadata.allMetadata objectForKey:@"value"]];
        [actor setProfileURL:url];
    }
  }
}

// display some UI element for the user to interact with
Run Code Online (Sandbox Code Playgroud)

到斯威夫特

func metadataUpdated (notification: NSNotification!) {

    if moviePlayer?.timedMetadata != nil && moviePlayer?.timedMetadata.count > 0 {


        for MPTimedMetadata in [moviePlayer?.timedMetadata] {

            if MPTimedMetadata?.description  == ("TPE1") {

                let name = ("value")

            }

            if MPTimedMetadata?.description  == ("WXXX") {

                var url = NSURL.observeValueForKeyPath("value")

            }
        } 
}
println("Things are kind of working")
}
}
Run Code Online (Sandbox Code Playgroud)

对于我的生活,虽然我无法弄清楚如何将元数据转换为任何可操作的代码.我真的需要创建一个重定向到元数据中携带的URL的按钮,但不能将其转换为String.任何帮助是极大的赞赏.这是我到目前为止所拥有的.

import UIKit

import MediaPlayer



class ViewController: UIViewController {


var moviePlayer: MPMoviePlayerController?


var youtube = ""

override func viewDidLoad() {

    super.viewDidLoad()

    // Do any additional setup after loading the view, typically from a nib.


    let url = NSURL(string: "http://path/to/video.m3u8")



    moviePlayer = MPMoviePlayerController(contentURL: url)



    if let player = moviePlayer {



        player.view.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height)

        player.view.sizeToFit()

        player.scalingMode = MPMovieScalingMode.None





        player.movieSourceType = MPMovieSourceType.Streaming

        //player.repeatMode = MPMovieRepeatMode.One





        player.play()



        self.view.addSubview(player.view)



        NSNotificationCenter.defaultCenter().addObserver(

            self,

            selector: "metadataUpdated:",

            name: MPMoviePlayerTimedMetadataUpdatedNotification,

            object: nil)



    }

}



override func didReceiveMemoryWarning() {

    super.didReceiveMemoryWarning()

    // Dispose of any resources that can be recreated.

}



func metadataUpdated (notification: NSNotification!) {






    if moviePlayer?.timedMetadata != nil && moviePlayer?.timedMetadata.count > 0 {


        for MPTimedMetadata in [moviePlayer?.timedMetadata] {

            if MPTimedMetadata?.description  == ("TPE1") {

                let name = ("value")



            }

            if MPTimedMetadata?.description  == ("WXXX") {

                var url = NSURL.observeValueForKeyPath("value")



            }


        }


}
println("Things are kind of working")


}


}
Run Code Online (Sandbox Code Playgroud)

Jac*_*rks 3

所以我让它工作了,但最终放弃了 MPMovieController,选择了 AVPlayer。这是我的代码,以及帮助我​​使其发挥作用的另一篇文章的链接。

使用 AVPlayer 的定时元数据

import UIKit

import MediaPlayer
import AVFoundation

var youtubeRequest: NSURLRequest! = nil
var player : AVPlayer? = nil

var url:NSString!


class ViewController: UIViewController {


var moviePlayer: MPMoviePlayerController?
var movieItem: AVPlayerItem!
var Player: AVPlayer!

var playerLayer : AVPlayerLayer? = nil
var asset : AVAsset? = nil
var playerItem: AVPlayerItem!

var youtubeRequest: NSURLRequest! = nil

@IBOutlet var playButtonOutlet: UIBarButtonItem!

@IBAction func playButtonAction(sender: AnyObject) {player?.play()
    playButtonOutlet.enabled = false

}

@IBOutlet var videoView: UIView!
@IBAction func loadURL(sender: AnyObject) {player?.pause()
    playButtonOutlet.enabled = true
}
@IBOutlet var urlButton: UIButton!
override func viewDidLoad() {

    super.viewDidLoad()



    // Do any additional setup after loading the view, typically from a nib.

    urlButton.enabled = false

    let videoURL = NSURL(string: "http://path/to/video.m3u8")
    playButtonOutlet.enabled = false

    movieItem = AVPlayerItem(URL: NSURL(string: "http://path/to/video.m3u8"))
    movieItem.addObserver(self, forKeyPath: "timedMetadata", options: nil, context: nil)
    Player = AVPlayer(playerItem: movieItem)

    var metaArray: Array<Any> = [moviePlayer?.timedMetadata]







    asset = AVAsset.assetWithURL(videoURL) as? AVAsset
    playerItem = AVPlayerItem(asset: asset)
    playerItem = AVPlayerItem(URL: NSURL(string: "http://path/to/video.m3u8"))
    playerItem.addObserver(self, forKeyPath: "timedMetadata", options: nil, context: nil)
    playerItem.addObserver(self, forKeyPath: "presentationSize", options: nil, context: nil)
    player = AVPlayer(playerItem: playerItem)



    playerLayer = AVPlayerLayer(player: player)
    playerLayer!.frame = videoView.bounds

    videoView.layer.addSublayer(self.playerLayer)

    player!.play()

    NSNotificationCenter.defaultCenter().addObserver(

        self,

        selector: "rotated",

        name: UIDeviceOrientationDidChangeNotification,

        object: nil)


}

    override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) -> Void {

        if keyPath != "timedMetadata" { return }

        var data: AVPlayerItem = object as AVPlayerItem

        var urlError = false

        for item in data.timedMetadata as [AVMetadataItem] {

            println(item.stringValue)
            var metaArray: Array<Any> = [playerItem?.timedMetadata]
            println("Total objects in array \(metaArray[0])")


            var data = item.stringValue

          url = NSString(string: data) as NSString!



            if url != nil {

             urlButton.enabled = true

                println("The url is \(url)")




            } else {

                urlError = true

            }


            var urlRedirect = NSURL(fileURLWithPath: "\(url)")


            println("The url is \(urlRedirect)")

        }


    }

override func didReceiveMemoryWarning() {

    super.didReceiveMemoryWarning()

    // Dispose of any resources that can be recreated.

}

func rotated()
{
    if(UIDeviceOrientationIsLandscape(UIDevice.currentDevice().orientation))
    {
     self.navigationController?.navigationBarHidden = true
        playerLayer?.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height)
        playerLayer?.frame = CGRectMake(0,0,self.view.frame.size.width,self.view.frame.size.height)

        println("landscape")
    }

    if(UIDeviceOrientationIsPortrait(UIDevice.currentDevice().orientation))
    {
        self.navigationController?.navigationBarHidden = false
        playerLayer!.frame = videoView.bounds

        println("portraight")
    }

 }


}
Run Code Online (Sandbox Code Playgroud)