2017-01-14 7 views
1

Я пытаюсь загрузить видео на Mac с помощью быстрых 3 и MLMediaLibrary от Apple. Я загрузил образец кода из apple, который загружает фотографии с URL: https://developer.apple.com/library/content/samplecode/MediaLibraryLoader/Introduction/Intro.html#//apple_ref/doc/uid/TP40017375Загружать видео на Mac OS с помощью MediaLibrary

Я пытаюсь изменить код загрузки видео, а не фотографий. Ниже приведен пример моего кода. Я понял, что MLMediaLoadIncludeSourcesKey должен быть MLMediaSourcePhotosIdentifier только для доступа к видео в приложении «Фотографии». Однако он не загружает видео и не дает сообщение «неподдерживаемый формат поверхности: 420f» в консоли.

Что я могу сделать, чтобы показывать только видео?

import Cocoa 
import MediaLibrary 

class IconViewBox : NSBox { 
override func hitTest(_ aPoint: NSPoint) -> NSView? { 
    // Don't allow any mouse clicks for subviews in this NSBox. 
    return nil 
    } 
} 

// MARK: - 

class ViewController: NSViewController, NSCollectionViewDelegate { 

// MARK: - Types 

// Keys describing the dictionary for each photo loaded. 
private struct ItemKeys { 
    static let imageKey = "icon" 
    static let nameKey = "name" 
} 

// MLMediaLibrary property values for KVO. 
private struct MLMediaLibraryPropertyKeys { 
    static let mediaSourcesKey = "mediaSources" 
    static let rootMediaGroupKey = "rootMediaGroup" 
    static let mediaObjectsKey = "mediaObjects" 
    static let contentTypeKey = "contentType" 
} 

// MARK: - Properties 

/** 
The KVO contexts for `MLMediaLibrary`. 
This provides a stable address to use as the `context` parameter for KVO observation methods. 
*/ 
private var mediaSourcesContext = 1 
private var rootMediaGroupContext = 2 
private var mediaObjectsContext = 3 

private var photoSize = CGSize(width: 168, height: 145) 

// Contains an array of dictionaries describing each photo (refer to ItemKeys for key/values). 
@IBOutlet weak var arrayController: NSArrayController! 

@IBOutlet weak var collectionView: NSCollectionView! 
@IBOutlet private weak var noPhotosLabel: NSTextField! 
@IBOutlet private weak var activityIndicator: NSProgressIndicator! 

// MLMediaLibrary instances for loading the photos. 
private var mediaLibrary: MLMediaLibrary! 
private var mediaSource: MLMediaSource! 
private var rootMediaGroup: MLMediaGroup! 

// MARK: - View Controller Lifecycle 

override func viewDidLoad() { 

    super.viewDidLoad() 

    // Start progress indicator in case fetching the photos from the photo library takes time. 
    self.activityIndicator.isHidden = false 
    self.activityIndicator.startAnimation(self) 

    self.collectionView.minItemSize = self.photoSize 
    self.collectionView.maxItemSize = self.photoSize 

    self.arrayController.setSelectionIndex(-1) // No selection to start out with. 

    // Setup the media library to load only photos, don't include other source types. 
    let options: [String : AnyObject] = 
     [MLMediaLoadSourceTypesKey: MLMediaSourceType.image.rawValue as AnyObject, 
     MLMediaLoadIncludeSourcesKey: [MLMediaSourcePhotosIdentifier, MLMediaSourceiPhotoIdentifier] as AnyObject] 

    // Create our media library instance to get our photo. 
    mediaLibrary = MLMediaLibrary(options: options) 
    // We want to be called when media sources come in that's available (via observeValueForKeyPath). 
    self.mediaLibrary.addObserver(self, 
            forKeyPath: MLMediaLibraryPropertyKeys.mediaSourcesKey, 
            options: NSKeyValueObservingOptions.new, 
            context: &mediaSourcesContext) 
    if (self.mediaLibrary.mediaSources != nil) {} // Reference returns nil but starts the asynchronous loading. 
} 

deinit { 

    // Make sure to remove us as an observer before "mediaLibrary" is released. 
    self.mediaLibrary.removeObserver(self, forKeyPath: MLMediaLibraryPropertyKeys.mediaSourcesKey, context:&mediaSourcesContext) 
} 

// MARK: - NSCollectionViewDataSource 

func numberOfSectionsInCollectionView(_ collectionView: NSCollectionView) -> Int { 

    return 1 
} 

func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int { 

    let photos = self.arrayController.arrangedObjects as! NSArray 
    print("photos.count \(photos.count)") 
    return photos.count 
} 

func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAtIndexPath indexPath: IndexPath) -> NSCollectionViewItem { 

    let item = collectionView.makeItem(withIdentifier: "IconItem", for:indexPath) 
    let photos = self.arrayController.arrangedObjects as! NSArray 
    let iconInfo = photos[(indexPath as NSIndexPath).item] 
    item.representedObject = iconInfo 
    return item 
} 

// MARK: - NSCollectionViewDelegate 

func collectionView(_ collectionView: NSCollectionView, didSelectItemsAt indexPaths: Set<IndexPath>) { 

    if let itemIndexPath = indexPaths.first { 
     let photos = self.arrayController.arrangedObjects as! NSArray 
     let itemDict = photos[((itemIndexPath as NSIndexPath).item)] as! NSDictionary 
     if let itemTitle = itemDict[ItemKeys.nameKey] as? String { 
      if (itemTitle.characters.count > 0) { 
       print("selected photo: '\(itemTitle)'") 
      } 
      else { 
       print("selected photo: <no title>") 
      } 
     } 
    } 
} 

// MARK: - Utilities 

/// Helps to make sure the media object is the photo format we want. 
private func isValidImage(_ mediaObject: MLMediaObject) -> Bool { 

    var isValidImage = false 

    let attrs = mediaObject.attributes 
    let contentTypeStr = attrs[MLMediaLibraryPropertyKeys.contentTypeKey] as! String 

    // We only want photos, not movies or older PICT formats (PICT image files are not supported in a sandboxed environment). 
    if ((contentTypeStr != kUTTypePICT as String) && (contentTypeStr != kUTTypeQuickTimeMovie as String)) 
    { 
     isValidImage = true 
    } 
    print("isValidImage: \(isValidImage)") 
    //return isValidImage 
    return true 
} 

/// Obtains the title of the MLMediaObject (either the meta name or the last component of the URL). 
func imageTitle(_ fromMediaObject: MLMediaObject) -> String { 

    guard let title = fromMediaObject.attributes["name"] else { 
     return fromMediaObject.url!.lastPathComponent 
    } 
    return title as! String 
} 


// MARK: - Photo Loading 

/// Observer for all key paths returned from the MLMediaLibrary. 
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { 

    if (keyPath == MLMediaLibraryPropertyKeys.mediaSourcesKey && context == &mediaSourcesContext && object! is MLMediaLibrary) { 

     // The media sources have loaded, we can access the its root media. 

     if let mediaSource = self.mediaLibrary.mediaSources?[MLMediaSourcePhotosIdentifier] { 
      self.mediaSource = mediaSource 
     } 
     else if let mediaSource = self.mediaLibrary.mediaSources?[MLMediaSourceiPhotoIdentifier] { 
      self.mediaSource = mediaSource 
     } 
     else { 
      // Can't find any media sources. 
      self.noPhotosLabel.isHidden = false 

      // Stop progress indicator. 
      self.activityIndicator.isHidden = true 
      self.activityIndicator.stopAnimation(self) 

      return // No photos found. 
     } 

     // Media Library is loaded now, we can access mediaSource for photos 
     self.mediaSource.addObserver(self, 
            forKeyPath: MLMediaLibraryPropertyKeys.rootMediaGroupKey, 
            options: NSKeyValueObservingOptions.new, 
            context: &rootMediaGroupContext) 

     // Obtain the media grouping (reference returns nil but starts asynchronous loading). 
     if (self.mediaSource.rootMediaGroup != nil) {} 
    } 
    else if (keyPath == MLMediaLibraryPropertyKeys.rootMediaGroupKey && context == &rootMediaGroupContext && object! is MLMediaSource) { 

     // The root media group is loaded, we can access the media objects. 

     // Done observing for media groups. 
     self.mediaSource.removeObserver(self, forKeyPath: MLMediaLibraryPropertyKeys.rootMediaGroupKey, context:&rootMediaGroupContext) 

     self.rootMediaGroup = self.mediaSource.rootMediaGroup 
     self.rootMediaGroup.addObserver(self, 
             forKeyPath: MLMediaLibraryPropertyKeys.mediaObjectsKey, 
             options: NSKeyValueObservingOptions.new, 
             context: &mediaObjectsContext) 

     // Obtain the all the photos, (reference returns nil but starts asynchronous loading). 
     if (self.rootMediaGroup.mediaObjects != nil) {} 
    } 
    else if (keyPath == MLMediaLibraryPropertyKeys.mediaObjectsKey && context == &mediaObjectsContext && object! is MLMediaGroup) { 

     // The media objects are loaded, we can now finally access each photo. 

     // Done observing for media objects that group. 
     self.rootMediaGroup.removeObserver(self, forKeyPath: MLMediaLibraryPropertyKeys.mediaObjectsKey, context:&mediaObjectsContext) 

     // Stop progress indicator since we know if we have photos (or not). 
     self.activityIndicator.isHidden = true 
     self.activityIndicator.stopAnimation(self) 

     let mediaObjects = self.rootMediaGroup.mediaObjects 
     if (mediaObjects != nil && mediaObjects!.count > 0) { 
      // Add photos to the array, to be used in our NSCollectionView. 
      for mediaObject in mediaObjects! { 
       if (self.isValidImage(mediaObject)) { // Make sure the media object is a photo. 

        let title = self.imageTitle(mediaObject) 

        if let image = NSImage.init(contentsOf: mediaObject.thumbnailURL!) { 
         let iconItem : Dictionary = [ItemKeys.imageKey: image, ItemKeys.nameKey: title] as [String : Any] 
         self.arrayController.addObject(iconItem) 
        } 
       } 
      } 

      self.collectionView.reloadData() 

     } 
     else { 
      // No photos available. 
      self.noPhotosLabel.isHidden = false 
     } 

     self.rootMediaGroup = nil // We are done with this. 
    } 
    else { 
     super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) 
    } 
} 

} 

Может кто-то прольет здесь немного света. Я новичок и документации для Mac недостаточно, хотя я могу многое найти в IOS.

+0

Получение одинаковой ошибки, различное использование. Моя появляется, когда я просматриваю свой просмотр коллекции, предполагая, что это связано с загрузкой изображения. Это только началось, когда я вернулся в новую машину в эти выходные. Не было в пятницу, только началось. : / –

ответ