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

时间:2015-03-27 21:10:09

标签: swift ios8 metadata mpmovieplayercontroller

我正在尝试在swift中复制此https://jmacmullin.wordpress.com/2010/11/03/adding-meta-data-to-video-in-ios/

以下是Jake代码的视频......

Objective C Timed Metadat in HLS stream

以下是类似内容的附加链接......

http://cloudfields.net/blog/metadata-audiostream-mpmovieplayercontroller/

当我的视频播放时,元数据应该会更新按钮,以便在点击时重定向到网页浏览中的特定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];

到Swift Code

       NSNotificationCenter.defaultCenter().addObserver(
            self,
            selector: "metadataUpdated",
            name: MPMoviePlayerTimedMetadataUpdatedNotification,
            object: nil)

杰克的功能

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

到Swift

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")
}
}

对于我的生活,虽然我无法弄清楚如何将元数据转换为任何可操作的代码。我真的需要创建一个重定向到元数据中携带的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")


}


}

1 个答案:

答案 0 :(得分:3)

所以我让这个工作,但最终沟渠MPMovieController选择AVPlayer。这是我的代码,以及帮助我​​实现其功能的另一篇帖子的链接。

Timed Metadata with 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")
    }

 }


}