iOS 下載和播放 M3U8

WLM3U 是一個用 Swift 實現的 M3U 工具。git

項目地址 github.com/WillieWangW…github

示例

clone 這個倉庫,接着執行 pod install 命令,而後運行示例項目。數組

要求

iOS Swift
9.0 + 5.0 +

安裝

WLM3U 可經過 CocoaPods 安裝,只需將如下行添加到 Podfile 便可緩存

pod 'WLM3U'
複製代碼

使用

解析 M3U 文件

let url = URL(string:"http://xxx.com/yyy.m3u8")! // M3U 文件的 URL
let size: Int = <#fileSize#>                     // 全部 ts 文件的總大小

WLM3U
    .attach(url: url, size: size, completion: { (result) in
        switch result {
        case .success(let model):
            model.name  // yyy
            model.tsArr // ts 文件數組
            ...
        case .failure(let error):
            print("attach failure " + error.localizedDescription)
        }
    })
複製代碼

下載 M3U 文件描述的 ts 文件

let url = URL(string:"http://xxx.com/yyy.m3u8")! // M3U 文件的 URL
let size: Int = <#fileSize#>                     // 全部 ts 文件的總大小

WLM3U
    .attach(url: url, size: size)
    .download(progress: { (progress, completedCount) in
        progress       // 當前下載的進度
        completedCount // 下載速度( B/S )
        
    }, completion: { (result) in
        switch result {
        case .success(let url):
            url // ts 文件所在的目錄
        case .failure(let error):
            print("download failure " + error.localizedDescription)
        }
    })
複製代碼

將下載的 ts 文件合併成一個文件

let url = URL(string:"http://xxx.com/yyy.m3u8")! // M3U 文件的 URL
let size: Int = <#fileSize#>                     // 全部 ts 文件的總大小

WLM3U
    .attach(url: url, size: size)
    .download()
    .combine(completion: { (result) in
        switch result {
        case .success(let url):
            url // 合併完成後文件所在的目錄
        case .failure(let error):
            print("combine failure " + error.localizedDescription)
        }
    })
複製代碼

自動獲取 ts 文件總大小

WLM3U 支持自動獲取全部文件的總大小,只需設置 calculateSize 參數便可:ruby

let url = URL(string:"http://xxx.com/yyy.m3u8")! // M3U 文件的 URL

WLM3U
    .attach(url: url, calculateSize: true)
    .download()
    .combine()
複製代碼

獲取大小的過程是異步的,能夠經過接收 TaskGetFileSizeProgressNotificationTaskGetFileSizeCompletionNotification 來獲取大小數據。異步

暫停與恢復任務

爲了簡化接口,WLM3U 沒有 暫停恢復 的概念,它們和 取消添加 是同樣的,因此:工具

須要暫停一個任務時,調用 cancel(url: URL)ui

須要取消一個任務時,調用 cancel(url: URL),並經過 folder(for url: URL) 獲取到此任務緩存目錄,並刪除它便可。url

須要添加一個任務時,調用 attach(url: URL)spa

須要恢復一個任務時,調用 attach(url: URL),若是本地存在以前的緩存,會自動繼續下載剩餘的文件。

監聽狀態

WLM3U 內置了幾個狀態的通知,你能夠接收這些通知來處理數據:

/// 下載進度發生變化時會發出的通知。
public let TaskProgressNotification: Notification.Name

/// 獲取文件總大小的進度發生變化時會發出的通知。
public let TaskGetFileSizeProgressNotification: Notification.Name

/// 獲取文件總大小完成時會發出的通知。
public let TaskGetFileSizeCompletionNotification: Notification.Name

/// 任務完成時會發出的通知。
public let TaskCompletionNotification: Notification.Name

/// 任務發生錯誤時會發出的通知。
public let TaskErrorNotification: Notification.Name
複製代碼

播放下載的文件

AVPlayer 與 WLM3U 暫不支持播放本地 ts 文件,這裏提供兩個簡單可行的替代方案。

使用 GCDWebServer 搭建本地服務

引入 GCDWebServer 庫:

pod "GCDWebServer"
複製代碼

建立本地 HTTP 服務來提供下載好的 ts 文件:

let server = GCDWebServer()
let path = <#folderPath#> // ts 文件所在的本地目錄
server.addGETHandler(forBasePath: "/",
                     directoryPath: path,
                     indexFilename: "file.m3u8",
                     cacheAge: 3600,
                     allowRangeRequests: true)
server.start()
複製代碼

使用 AVPlayer 來播放本地服務提供的 ts 文件:

let url = URL(string: "http://localhost:\(server.port)/file.m3u8")
let player = AVPlayer(url: url)
複製代碼

使用 FFmpeg 將 ts 文件轉碼成 mp4 文件

引入 mobile-ffmpeg-full 庫:

pod "mobile-ffmpeg-full"
複製代碼

執行轉碼命令:

let command = "-i 'ts文件所在的路徑' 'mp4文件要保存到的路徑'"

let result = MobileFFmpeg.execute(command)

if result == RETURN_CODE_SUCCESS {
    // 轉碼完成
}
複製代碼

接下來直接播放轉碼獲得的 mp4 文件便可。

做者

Willie, willie.wangwei@gmail.com

相關文章
相關標籤/搜索