\n<\/td>\n http:\/\/213.115.248.46:9000\/TR_-_ATV_HD_PLUS\/index.m3u8<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\nFirst of all, we need to\u00a0grab<\/strong>, then\u00a0map<\/strong>\u00a0the m3u file into an array of objects.<\/p>\n<\/div>\n<\/div>\n
\n
Parser Logic<\/h2>\n\n\n
\n
\n\n\n<\/td>\n \/\/<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/ m3u8Parse.swift<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/ M3U8ParseTutorial<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/ Created by Abdullah Yal\u00e7\u0131n on 6.07.2022.<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/<\/span><\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n import<\/span> Foundation<\/span><\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n struct<\/span> MediaItem<\/span>: Codable <\/span>{<\/td>\n<\/tr>\n\n<\/td>\n var<\/span> duration: Int<\/span>?<\/span><\/td>\n<\/tr>\n\n<\/td>\n var<\/span> title: String<\/span>?<\/span><\/td>\n<\/tr>\n\n<\/td>\n var<\/span> urlString: String<\/span>?<\/span><\/td>\n<\/tr>\n\n<\/td>\n }<\/td>\n<\/tr>\n \n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n class<\/span> ParseHelper<\/span> {<\/td>\n<\/tr>\n\n<\/td>\n func<\/span> parseM3U<\/span>(contentsOfFile<\/span><\/span>: String<\/span>) -><\/span> [MediaItem] {<\/td>\n<\/tr>\n\n<\/td>\n var<\/span> mediaItems =<\/span> [MediaItem]()<\/td>\n<\/tr>\n\n<\/td>\n contentsOfFile.enumerateLines<\/span>(invoking<\/span>: { line, stop in<\/span><\/td>\n<\/tr>\n\n<\/td>\n if<\/span> line.hasPrefix<\/span>(“<\/span>#EXTINF:“<\/span><\/span>) {<\/td>\n<\/tr>\n\n<\/td>\n let<\/span> infoLine =<\/span> line.replacingOccurrences<\/span>(of<\/span>: “<\/span>#EXTINF:“<\/span><\/span>, with<\/span>: “<\/span>“<\/span><\/span>)<\/td>\n<\/tr>\n\n<\/td>\n let<\/span> infos =<\/span> Array<\/span>(infoLine.components<\/span>(separatedBy<\/span>: “<\/span>,“<\/span><\/span>))<\/td>\n<\/tr>\n\n<\/td>\n if<\/span> let<\/span> durationString =<\/span> infos.first<\/span>, let<\/span> duration =<\/span> Int<\/span>(durationString) {<\/td>\n<\/tr>\n\n<\/td>\n let<\/span> mediaItem =<\/span> MediaItem<\/span>(duration<\/span>: duration, title<\/span>: infos.last<\/span>?<\/span>.trimmingCharacters<\/span>(in<\/span>: .whitespaces<\/span>), urlString<\/span>: nil<\/span>)<\/td>\n<\/tr>\n\n<\/td>\n mediaItems.append<\/span>(mediaItem)<\/td>\n<\/tr>\n\n<\/td>\n }<\/td>\n<\/tr>\n \n<\/td>\n } else<\/span> {<\/td>\n<\/tr>\n\n<\/td>\n if<\/span> mediaItems.count<\/span> ><\/span> 0<\/span> {<\/td>\n<\/tr>\n\n<\/td>\n mediaItems[mediaItems.count<\/span> –<\/span> 1<\/span>].urlString<\/span> =<\/span> line<\/td>\n<\/tr>\n\n<\/td>\n }<\/td>\n<\/tr>\n \n<\/td>\n }<\/td>\n<\/tr>\n \n<\/td>\n })<\/td>\n<\/tr>\n \n<\/td>\n return<\/span> mediaItems<\/td>\n<\/tr>\n\n<\/td>\n }<\/td>\n<\/tr>\n \n<\/td>\n }<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/figure>\nHere is a struct MediaItem, it includes\u00a0streamUrl<\/strong>,\u00a0title,<\/strong>\u00a0and\u00a0duration<\/strong>.<\/p>\n\nparseM3U function gets an m3u file content, which is presented in String format.<\/li>\n \u201c#EXTINF:\u201c\u00a0<\/em>word defines a playlist file.\u00a0<\/em>It looks up line by line, then maps into MediaItem.<\/li>\n<\/ul>\n<\/div>\n<\/div>\n
\n
ViewController to stream<\/h2>\n\n\n
\n
\n\n\n<\/td>\n \/\/<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/ IPTVViewController.swift<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/ avemobilecms<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/ Created by Abdullah Yal\u00e7\u0131n on 6.07.2022.<\/span><\/td>\n<\/tr>\n\n<\/td>\n \/\/<\/span><\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n import<\/span> Foundation<\/span><\/td>\n<\/tr>\n\n<\/td>\n import<\/span> AVKit<\/span><\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n class<\/span> IPTVViewController<\/span>: UIViewController <\/span>{<\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n @IBOutlet<\/span> private<\/span> weak<\/span> var<\/span> listTableView: UITableView!<\/span><\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n private<\/span> var<\/span> mediaList: [MediaItem] =<\/span> []<\/td>\n<\/tr>\n\n<\/td>\n private<\/span> let<\/span> m3uFileLink =<\/span> “<\/span>myUrl.cdn.net\/example.m3u“<\/span><\/span><\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n override<\/span> func<\/span> viewDidLoad<\/span>() {<\/td>\n<\/tr>\n\n<\/td>\n super<\/span>.viewDidLoad<\/span>()<\/td>\n<\/tr>\n\n<\/td>\n <\/td>\n<\/tr>\n \n<\/td>\n if<\/span> let<\/span> url =<\/span> URL<\/span>(string<\/span>: m3uFileLink) {<\/td>\n<\/tr>\n\n<\/td>\n do<\/span> {<\/td>\n<\/tr>\n\n<\/td>\n