M3U8 Framework for parsing and handling .m3u8 files (based on Apple document)
Use something like the following in your Podfile
(some adjustments might be needed depending on the case).
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'GoSwiftyM3U8', '~> 1.0.0'
Afterwards run pod install
from the terminal in the same folder of the Podfile
(for details of the installation and usage of CocoaPods, visit it's official web site).
It is possible to have multiple pods with different versions of Swift, this might force you to add post install handling in your Podfile
.
For technical docs please see API. Here are some basic usage examples of usage, there are 2 main ways for using the framework:
- Fetching the playlist text on your own and only use the parser.
- Use
M3U8Manager
to fetch and parse the playlist (a custom playlist fetcher can be provided if needed).
- Another option can be using the
PlaylistOperation
with your own queue and write the logic for fetching whichever playlists are needed.
Using M3U8Parser
A simple example of parsing a playlist:
let playlist = /* your playlist text from local/remote content */
let baseUrl = /* base url for the provided playlist */
let playlistType = /* the type of the playlist, can be: master/video/audio/subtitles */
let parser = M3U8Parser()
let params = M3U8Parser.Params(playlist: playlist, playlistType: .master, baseUrl: baseUrl)
let extraParams = M3U8Parser.ExtraParams(customRequiredTags: nil, extraTypes: nil, linePostProcessHandler: nil) // optional
do {
let playlistResult = try parser.parse(params: params, extraParams: extraParams)
// if our playlist was of type master you can unwrap the result like this:
if case let .master(masterPlaylist) = playlistResult else {
// use masterPlaylist
}
} catch {
// handle error
}
Additional Info:
- The parser is synchronous meaning if you want it on a background queue you will need to handle it.
- The parser can be cancelled but because it is synchronous to be able to cancel the call to
parse()
must be async. - You can reuse the parser object to parser multiple list synchronously.
Using M3U8Manager
M3U8Manager
can fetch and parse single playlist or multiple ones, only media playlists for multiple because we must have master playlist before fetching media playlists.
You can also cancel all manager tasks using cancel()
.
Single playlist handling:
let manager = M3U8Manager()
let playlistFetcher = /* You can use a custom playlist fetcher or nil to use the default one */
let params = PlaylistOperation.Params(fetcher: playlistFetcher, url: playlistUrl, playlistType: playlistType)
let parserExtraParams = M3U8Parser.ExtraParams(customRequiredTags: nil, extraTypes: nil, linePostProcessHandler: nil) // optional
let extraParams = PlaylistOperation.ExtraParams(parser: parserExtraParams) // optional
let operationData = M3U8Manager.PlaylistOperationData(params: params, extraParams: extraParams)
let playlistType = /* the type of the playlist from the result (can be MasterPlaylist.self/MediaPlaylist.self) */
manager.fetchAndParsePlaylist(from: operationData, playlistType: playlistType) { (result) in
switch result {
case .success(let playlist):
// handle playlist
case .failure(let error): // handle the error
case .cancelled: // handle cancelled
}
}
Multiple playlists:
let manager = M3U8Manager()
let playlistFetcher = /* You can use a custom playlist fetcher or nil to use the default one */
let params1 = PlaylistOperation.Params(fetcher: playlistFetcher, url: firstUrl, playlistType: playlistType)
let parserExtraParams1 = M3U8Parser.ExtraParams(customRequiredTags: nil, extraTypes: nil, linePostProcessHandler: nil)
let extraParams1 = PlaylistOperation.ExtraParams(parser: parserExtraParams1)
let operationData1 = M3U8Manager.PlaylistOperationData(params: params1, extraParams: extraParams1)
let params2 = PlaylistOperation.Params(fetcher: playlistFetcher, url: secondUrl, playlistType: playlistType)
let parserExtraParams2 = M3U8Parser.ExtraParams(customRequiredTags: nil, extraTypes: nil, linePostProcessHandler: nil)
let extraParams2 = PlaylistOperation.ExtraParams(parser: parserExtraParams2)
let operationData2 = M3U8Manager.PlaylistOperationData(params: params2, extraParams: extraParams2)
let operationsData = [operationData1, operationData2]
manager.fetchAndParseMediaPlaylists(from: operationsData) { (result) in
switch result {
case .success(let playlists):
// handle playlists
case .failure(let error): // handle the error
case .cancelled: // handle cancelled
}
}