123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294 |
- /*****************************************************************************
- * VLCMediaLibraryManager.swift
- * VLC for iOS
- *****************************************************************************
- * Copyright © 2018 VideoLAN. All rights reserved.
- * Copyright © 2018 Videolabs
- *
- * Authors: Soomin Lee <bubu # mikan.io>
- *
- * Refer to the COPYING file of the official project for license.
- *****************************************************************************/
- extension Notification.Name {
- static let VLCNewFileAddedNotification = Notification.Name("NewFileAddedNotification")
- }
- // For objc
- extension NSNotification {
- @objc static let VLCNewFileAddedNotification = Notification.Name.VLCNewFileAddedNotification
- }
- @objc protocol MediaLibraryObserver: class {
- // Video
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didUpdateVideo video: [VLCMLMedia])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didDeleteMediaWithIds ids: [NSNumber])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddVideos videos: [VLCMLMedia])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddShowEpisodes showEpisodes: [VLCMLMedia])
- // Audio
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddAudios audios: [VLCMLMedia])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddArtists artists: [VLCMLArtist])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didDeleteArtistsWithIds artistsIds: [NSNumber])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddAlbums albums: [VLCMLAlbum])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didDeleteAlbumsWithIds albumsIds: [NSNumber])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddAlbumTracks albumTracks: [VLCMLMedia])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddGenres genres: [VLCMLGenre])
- // Playlist
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didAddPlaylists playlists: [VLCMLPlaylist])
- @objc optional func medialibrary(_ medialibrary: VLCMediaLibraryManager,
- didDeletePlaylistsWithIds playlistsIds: [NSNumber])
- }
- class VLCMediaLibraryManager: NSObject {
- private static let databaseName: String = "medialibrary.db"
- private var databasePath: String!
- private var thumbnailPath: String!
- // Using ObjectIdentifier to avoid duplication and facilitate
- // identification of observing object
- private var observers = [ObjectIdentifier: Observer]()
- private lazy var medialib: VLCMediaLibrary = {
- let medialibrary = VLCMediaLibrary()
- medialibrary.delegate = self
- return medialibrary
- }()
- override init() {
- super.init()
- setupMediaLibrary()
- NotificationCenter.default.addObserver(self, selector: #selector(reload),
- name: .VLCNewFileAddedNotification, object: nil)
- }
- // MARK: Private
- private func setupMediaLibrary() {
- guard let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first,
- let dbPath = NSSearchPathForDirectoriesInDomains(.libraryDirectory, .userDomainMask, true).first else {
- preconditionFailure("VLCMediaLibraryManager: Unable to init medialibrary.")
- }
- databasePath = dbPath + "/" + VLCMediaLibraryManager.databaseName
- thumbnailPath = documentPath
- let medialibraryStatus = medialib.setupMediaLibrary(databasePath: databasePath,
- thumbnailPath: thumbnailPath)
- switch medialibraryStatus {
- case .success:
- guard medialib.start() else {
- assertionFailure("VLCMediaLibraryManager: Medialibrary failed to start.")
- return
- }
- medialib.reload()
- medialib.discover(onEntryPoint: "file://" + documentPath)
- case .alreadyInitialized:
- assertionFailure("VLCMediaLibraryManager: Medialibrary already initialized.")
- case .failed:
- preconditionFailure("VLCMediaLibraryManager: Failed to setup medialibrary.")
- case .dbReset:
- // should still start and discover but warn the user that the db has been wipped
- assertionFailure("VLCMediaLibraryManager: The database was resetted, please re-configure.")
- }
- }
- // MARK: Internal
- @objc func reload() {
- medialib.reload()
- }
- /// Returns number of *ALL* files(audio and video) present in the medialibrary database
- func numberOfFiles() -> Int {
- var media = medialib.audioFiles(with: .filename, desc: false)
- media += medialib.videoFiles(with: .filename, desc: false)
- return media.count
- }
- /// Returns *ALL* file found for a specified VLCMLMediaType
- ///
- /// - Parameter type: Type of the media
- /// - Returns: Array of VLCMLMedia
- func media(ofType type: VLCMLMediaType, sortingCriteria sort: VLCMLSortingCriteria = .filename, desc: Bool = false) -> [VLCMLMedia] {
- return type == .video ? medialib.videoFiles(with: sort, desc: desc) : medialib.audioFiles(with: sort, desc: desc)
- }
- func genre(sortingCriteria sort: VLCMLSortingCriteria = .default, desc: Bool = false) -> [VLCMLGenre] {
- return medialib.genres(with: sort, desc: desc)
- }
- }
- // MARK: - Observer
- private extension VLCMediaLibraryManager {
- struct Observer {
- weak var observer: MediaLibraryObserver?
- }
- }
- extension VLCMediaLibraryManager {
- func addObserver(_ observer: MediaLibraryObserver) {
- let identifier = ObjectIdentifier(observer)
- observers[identifier] = Observer(observer: observer)
- }
- func removeObserver(_ observer: MediaLibraryObserver) {
- let identifier = ObjectIdentifier(observer)
- observers.removeValue(forKey: identifier)
- }
- }
- // MARK: MediaLibrary - Audio methods
- extension VLCMediaLibraryManager {
- func getArtists(sortingCriteria sort: VLCMLSortingCriteria = .artist, desc: Bool = false) -> [VLCMLArtist] {
- return medialib.artists(with: sort, desc: desc, all: true)
- }
- func getAlbums(sortingCriteria sort: VLCMLSortingCriteria = .album, desc: Bool = false) -> [VLCMLAlbum] {
- return medialib.albums(with: sort, desc: desc)
- }
- }
- // MARK: MediaLibrary - Video methods
- extension VLCMediaLibraryManager {
- }
- // MARK: MediaLibrary - Playlist methods
- extension VLCMediaLibraryManager {
- func createPlaylist(with name: String) -> VLCMLPlaylist {
- return medialib.createPlaylist(withName: name)
- }
- func deletePlaylist(with identifier: VLCMLIdentifier) -> Bool {
- return medialib.deletePlaylist(withIdentifier: identifier)
- }
- func getPlaylists(sortingCriteria sort: VLCMLSortingCriteria = .default, desc: Bool = false) -> [VLCMLPlaylist] {
- return medialib.playlists(with: sort, desc: desc)
- }
- }
- // MARK: - VLCMediaLibraryDelegate - Media
- extension VLCMediaLibraryManager: VLCMediaLibraryDelegate {
- func medialibrary(_ medialibrary: VLCMediaLibrary, didAddMedia media: [VLCMLMedia]) {
- let videos = media.filter {( $0.type() == .video )}
- let audio = media.filter {( $0.type() == .audio )}
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didAddVideos: videos)
- observer.value.observer?.medialibrary?(self, didAddAudios: audio)
- }
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didUpdateMedia media: [VLCMLMedia]) {
- let showEpisodes = media.filter {( $0.subtype() == .showEpisode )}
- let albumTrack = media.filter {( $0.subtype() == .albumTrack )}
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didAddShowEpisodes: showEpisodes)
- observer.value.observer?.medialibrary?(self, didAddAlbumTracks: albumTrack)
- }
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteMediaWithIds mediaIds: [NSNumber]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didDeleteMediaWithIds: mediaIds)
- }
- }
- }
- // MARK: - VLCMediaLibraryDelegate - Artists
- extension VLCMediaLibraryManager {
- func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd artists: [VLCMLArtist]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didAddArtists: artists)
- }
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteArtistsWithIds artistsIds: [NSNumber]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didDeleteArtistsWithIds: artistsIds)
- }
- }
- }
- // MARK: - VLCMediaLibraryDelegate - Albums
- extension VLCMediaLibraryManager {
- func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd albums: [VLCMLAlbum]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didAddAlbums: albums)
- }
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didDeleteAlbumsWithIds albumsIds: [NSNumber]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didDeleteAlbumsWithIds: albumsIds)
- }
- }
- }
- // MARK: - VLCMediaLibraryDelegate - Playlists
- extension VLCMediaLibraryManager {
- func medialibrary(_ medialibrary: VLCMediaLibrary, didAdd playlists: [VLCMLPlaylist]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didAddPlaylists: playlists)
- }
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didDeletePlaylistsWithIds playlistsIds: [NSNumber]) {
- for observer in observers {
- observer.value.observer?.medialibrary?(self, didDeletePlaylistsWithIds: playlistsIds)
- }
- }
- }
- // MARK: - VLCMediaLibraryDelegate - Discovery
- extension VLCMediaLibraryManager {
- func medialibrary(_ medialibrary: VLCMediaLibrary, didStartDiscovery entryPoint: String) {
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didCompleteDiscovery entryPoint: String) {
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didProgressDiscovery entryPoint: String) {
- }
- func medialibrary(_ medialibrary: VLCMediaLibrary, didUpdateParsingStatsWithPercent percent: UInt32) {
- }
- }
|