{"id":1306,"date":"2023-01-13T10:49:20","date_gmt":"2023-01-13T07:49:20","guid":{"rendered":"https:\/\/www.atonomik.com\/?p=1306"},"modified":"2023-05-09T01:24:51","modified_gmt":"2023-05-08T22:24:51","slug":"how-to-video-stream-of-iptv-with-m3u8-parser-in-swift","status":"publish","type":"post","link":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/","title":{"rendered":"How to video stream of IPTV with m3u8 parser in Swift"},"content":{"rendered":"
\n

We all know building an iOS application requires some UI and Swift knowledge. While creating many standard features, UI components are placed, then an interaction and business layer is created in accordance with the design pattern used. But there are some features that the algorithms should be used to play a key role.\u00a0IPTV<\/strong>\u00a0feature is one of them.<\/p>\n<\/div>\n

<\/div>\n
\n

M3U File<\/h2>\n

m3u<\/a>\u00a0is a computer file format for a multimedia playlist. m3u8 includes\u00a0album artist<\/strong>,\u00a0track information<\/strong>,\u00a0display title<\/strong>, etc\u2026<\/p>\n

\n
<\/div>\n<\/figure>\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
<\/td>\n#EXTM3U<\/td>\n<\/tr>\n
<\/td>\n#EXTINF:0, TRT1<\/td>\n<\/tr>\n
<\/td>\nhttps:\/\/tv-trt1.medya.trt.com.tr\/master_720.m3u8<\/td>\n<\/tr>\n
<\/td>\n#EXTINF:0, TRT 1 HD<\/td>\n<\/tr>\n
<\/td>\nhttps:\/\/mn-nl.mncdn.com\/blutv_trt12\/live.m3u8<\/td>\n<\/tr>\n
<\/td>\n#EXTINF:0, TRT 1 FHD<\/td>\n<\/tr>\n
<\/td>\nhttp:\/\/213.115.248.46:9000\/TR_-_TRT_1_HD_PLUS\/index.m3u8<\/td>\n<\/tr>\n
<\/td>\n#EXTINF:0, ATV SD<\/td>\n<\/tr>\n
<\/td>\nhttp:\/\/azerbaijan1.livetv.az\/turkey\/atv_turk_sd\/playlist.m3u8<\/td>\n<\/tr>\n
<\/td>\n#EXTINF:0, ATV HD TR<\/td>\n<\/tr>\n
<\/td>\nhttps:\/\/trkvz-live.daioncdn.net\/atv\/atv_720p.m3u8<\/td>\n<\/tr>\n
<\/td>\n#EXTINF:0, ATV FHD<\/td>\n<\/tr>\n
<\/td>\nhttp:\/\/213.115.248.46:9000\/TR_-_ATV_HD_PLUS\/index.m3u8<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n

First 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\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
<\/td>\n\/\/<\/span><\/td>\n<\/tr>\n
<\/td>\n\/\/ m3u8Parse.swift<\/span><\/td>\n<\/tr>\n
<\/td>\n\/\/ M3U8ParseTutorial<\/span><\/td>\n<\/tr>\n
<\/td>\n\/\/<\/span><\/td>\n<\/tr>\n
<\/td>\n\/\/ Created by Abdullah Yal\u00e7\u0131n on 6.07.2022.<\/span><\/td>\n<\/tr>\n
<\/td>\n\/\/<\/span><\/td>\n<\/tr>\n
<\/td>\n<\/td>\n<\/tr>\n
<\/td>\nimport<\/span> Foundation<\/span><\/td>\n<\/tr>\n
<\/td>\n<\/td>\n<\/tr>\n
<\/td>\nstruct<\/span> MediaItem<\/span>: Codable <\/span>{<\/td>\n<\/tr>\n
<\/td>\nvar<\/span> duration: Int<\/span>?<\/span><\/td>\n<\/tr>\n
<\/td>\nvar<\/span> title: String<\/span>?<\/span><\/td>\n<\/tr>\n
<\/td>\nvar<\/span> urlString: String<\/span>?<\/span><\/td>\n<\/tr>\n
<\/td>\n}<\/td>\n<\/tr>\n
<\/td>\n<\/td>\n<\/tr>\n
<\/td>\nclass<\/span> ParseHelper<\/span> {<\/td>\n<\/tr>\n
<\/td>\nfunc<\/span> parseM3U<\/span>(contentsOfFile<\/span><\/span>: String<\/span>) -><\/span> [MediaItem] {<\/td>\n<\/tr>\n
<\/td>\nvar<\/span> mediaItems =<\/span> [MediaItem]()<\/td>\n<\/tr>\n
<\/td>\ncontentsOfFile.enumerateLines<\/span>(invoking<\/span>: { line, stop in<\/span><\/td>\n<\/tr>\n
<\/td>\nif<\/span> line.hasPrefix<\/span>(“<\/span>#EXTINF:“<\/span><\/span>) {<\/td>\n<\/tr>\n
<\/td>\nlet<\/span> infoLine =<\/span> line.replacingOccurrences<\/span>(of<\/span>: “<\/span>#EXTINF:“<\/span><\/span>, with<\/span>: “<\/span>“<\/span><\/span>)<\/td>\n<\/tr>\n
<\/td>\nlet<\/span> infos =<\/span> Array<\/span>(infoLine.components<\/span>(separatedBy<\/span>: “<\/span>,“<\/span><\/span>))<\/td>\n<\/tr>\n
<\/td>\nif<\/span> let<\/span> durationString =<\/span> infos.first<\/span>, let<\/span> duration =<\/span> Int<\/span>(durationString) {<\/td>\n<\/tr>\n
<\/td>\nlet<\/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
<\/td>\nmediaItems.append<\/span>(mediaItem)<\/td>\n<\/tr>\n
<\/td>\n}<\/td>\n<\/tr>\n
<\/td>\n} else<\/span> {<\/td>\n<\/tr>\n
<\/td>\nif<\/span> mediaItems.count<\/span> ><\/span> 0<\/span> {<\/td>\n<\/tr>\n
<\/td>\nmediaItems[mediaItems.count<\/span> –<\/span> 1<\/span>].urlString<\/span> =<\/span> line<\/td>\n<\/tr>\n
<\/td>\n}<\/td>\n<\/tr>\n
<\/td>\n}<\/td>\n<\/tr>\n
<\/td>\n})<\/td>\n<\/tr>\n
<\/td>\nreturn<\/span> mediaItems<\/td>\n<\/tr>\n
<\/td>\n}<\/td>\n<\/tr>\n
<\/td>\n}<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/figure>\n

Here is a struct MediaItem, it includes\u00a0streamUrl<\/strong>,\u00a0title,<\/strong>\u00a0and\u00a0duration<\/strong>.<\/p>\n

    \n
  • parseM3U 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\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
    <\/td>\n\/\/<\/span><\/td>\n<\/tr>\n
    <\/td>\n\/\/ IPTVViewController.swift<\/span><\/td>\n<\/tr>\n
    <\/td>\n\/\/ avemobilecms<\/span><\/td>\n<\/tr>\n
    <\/td>\n\/\/<\/span><\/td>\n<\/tr>\n
    <\/td>\n\/\/ Created by Abdullah Yal\u00e7\u0131n on 6.07.2022.<\/span><\/td>\n<\/tr>\n
    <\/td>\n\/\/<\/span><\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nimport<\/span> Foundation<\/span><\/td>\n<\/tr>\n
    <\/td>\nimport<\/span> AVKit<\/span><\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nclass<\/span> IPTVViewController<\/span>: UIViewController <\/span>{<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\n@IBOutlet<\/span> private<\/span> weak<\/span> var<\/span> listTableView: UITableView!<\/span><\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nprivate<\/span> var<\/span> mediaList: [MediaItem] =<\/span> []<\/td>\n<\/tr>\n
    <\/td>\nprivate<\/span> let<\/span> m3uFileLink =<\/span> “<\/span>myUrl.cdn.net\/example.m3u“<\/span><\/span><\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\noverride<\/span> func<\/span> viewDidLoad<\/span>() {<\/td>\n<\/tr>\n
    <\/td>\nsuper<\/span>.viewDidLoad<\/span>()<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nif<\/span> let<\/span> url =<\/span> URL<\/span>(string<\/span>: m3uFileLink) {<\/td>\n<\/tr>\n
    <\/td>\ndo<\/span> {<\/td>\n<\/tr>\n
    <\/td>\nlet<\/span> fileContents =<\/span> try<\/span> String<\/span>(contentsOf<\/span>: url, encoding<\/span>: .ascii<\/span>)<\/td>\n<\/tr>\n
    <\/td>\nmediaList =<\/span> ParseHelper<\/span>().parseM3U<\/span>(contentsOfFile<\/span>: fileContents)<\/td>\n<\/tr>\n
    <\/td>\nlistTableView.register<\/span>(UITableViewCell.self<\/span>, forCellReuseIdentifier<\/span>: UITableViewCell.reuseIdentifier<\/span>)<\/td>\n<\/tr>\n
    <\/td>\nlistTableView.delegate<\/span> =<\/span> self<\/span><\/td>\n<\/tr>\n
    <\/td>\nlistTableView.dataSource<\/span> =<\/span> self<\/span><\/td>\n<\/tr>\n
    <\/td>\n}catch<\/span> {<\/td>\n<\/tr>\n
    <\/td>\nprint<\/span>(error)<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nprivate<\/span> func<\/span> executeUrl<\/span>(row<\/span><\/span>: Int<\/span>) {<\/td>\n<\/tr>\n
    <\/td>\nif<\/span> let<\/span> urlString =<\/span> mediaList[row].urlString<\/span>, let<\/span> url =<\/span> URL<\/span>(string<\/span>: urlString) {<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nlet<\/span> player =<\/span> AVPlayer<\/span>(url<\/span>: url)<\/td>\n<\/tr>\n
    <\/td>\nlet<\/span> controller =<\/span> AVPlayerViewController<\/span>()<\/td>\n<\/tr>\n
    <\/td>\ncontroller.delegate<\/span> =<\/span> self<\/span><\/td>\n<\/tr>\n
    <\/td>\ncontroller.player<\/span> =<\/span> player<\/td>\n<\/tr>\n
    <\/td>\npresent<\/span>(controller, animated<\/span>: true<\/span>) {<\/td>\n<\/tr>\n
    <\/td>\nplayer.play<\/span>()<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nextension<\/span> IPTVViewController<\/span>: UITableViewDelegate<\/span>, UITableViewDataSource <\/span>{<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nfunc<\/span> tableView<\/span>(_<\/span> tableView<\/span>: UITableView, numberOfRowsInSection<\/span> section<\/span>: Int<\/span>) -><\/span> Int<\/span> {<\/td>\n<\/tr>\n
    <\/td>\nmediaList.count<\/span><\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nfunc<\/span> tableView<\/span>(_<\/span> tableView<\/span>: UITableView, cellForRowAt<\/span> indexPath<\/span>: IndexPath) -><\/span> UITableViewCell {<\/td>\n<\/tr>\n
    <\/td>\nlet<\/span> cell =<\/span> tableView.dequeueReusableCell<\/span>(withIdentifier<\/span>: UITableViewCell.reuseIdentifier<\/span>, for<\/span>: indexPath)<\/td>\n<\/tr>\n
    <\/td>\ncell.textLabel<\/span>?<\/span>.text<\/span> =<\/span> mediaList[indexPath.row<\/span>].title<\/span><\/td>\n<\/tr>\n
    <\/td>\nreturn<\/span> cell<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nfunc<\/span> tableView<\/span>(_<\/span> tableView<\/span>: UITableView, didSelectRowAt<\/span> indexPath<\/span>: IndexPath) {<\/td>\n<\/tr>\n
    <\/td>\ntableView.deselectRow<\/span>(at<\/span>: indexPath, animated<\/span>: true<\/span>)<\/td>\n<\/tr>\n
    <\/td>\nexecuteUrl<\/span>(row<\/span>: indexPath.row<\/span>)<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nextension<\/span> IPTVViewController<\/span>: AVPlayerViewControllerDelegate <\/span>{<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nfunc<\/span> playerViewController<\/span>(_<\/span> playerViewController<\/span>: AVPlayerViewController, failedToStartPictureInPictureWithError<\/span> error<\/span>: Error<\/span>) {<\/td>\n<\/tr>\n
    <\/td>\nprint<\/span>(error)<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n<\/td>\n<\/tr>\n
    <\/td>\nfunc<\/span> playerViewController<\/span>(_<\/span> playerViewController<\/span>: AVPlayerViewController,<\/td>\n<\/tr>\n
    <\/td>\nrestoreUserInterfaceForPictureInPictureStopWithCompletionHandler<\/span> completionHandler<\/span>: @escaping<\/span> (Bool<\/span>) -><\/span> Void<\/span>) {<\/td>\n<\/tr>\n
    <\/td>\npresent<\/span>(playerViewController, animated<\/span>: false<\/span>) {<\/td>\n<\/tr>\n
    <\/td>\ncompletionHandler<\/span>(true<\/span>)<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n
    <\/td>\n}<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<\/figure>\n
      \n
    • In this example, we grabbed an m3u file from a remote\u00a0CDN<\/strong>\u00a0provider. You can store it in a string or internal storage of your application.<\/li>\n
    • Build a listTableView to present media.<\/li>\n
    • AVKit can get a stream URL directly, which is built-in.<\/li>\n
    • AVPlayerViewControllerDelegate<\/strong>\u00a0is used for Picture-in-Picture option.<\/li>\n<\/ul>\n<\/div>\n
      <\/div>\n
      \n

      In order to activate Picture-in-Picture in your app<\/h2>\n
        \n
      • Enable \u201cAudio, Airplay, and Picture in Picture<\/em>\u201d mode in your app target.<\/li>\n
      • In your appDelegate -> didFinishLaunchingWithOptions function, set category and activate like below.<\/li>\n<\/ul>\n
        \n

        do<\/strong>\u00a0{<\/p>\n

        try<\/strong>\u00a0AVAudioSession.sharedInstance().setCategory(.playback)<\/p>\n

        try<\/strong>\u00a0AVAudioSession.sharedInstance().setActive(true<\/strong>)<\/p>\n

        }catch<\/strong>\u00a0{<\/p>\n

        print(error)<\/p>\n

        }<\/p>\n<\/blockquote>\n<\/div>\n","protected":false},"excerpt":{"rendered":"

        We all know building an iOS application requires some UI and Swift knowledge. While creating many standard features, UI components are placed, then an interaction and business layer is created in accordance with the design pattern used. But there are some features that the algorithms should be used to play a key role.\u00a0IPTV\u00a0feature is one […]<\/p>\n","protected":false},"author":5,"featured_media":1309,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"link","meta":{"footnotes":""},"categories":[39],"tags":[],"class_list":["post-1306","post","type-post","status-publish","format-link","has-post-thumbnail","hentry","category-medium-2","post_format-post-format-link"],"yoast_head":"\nHow to video stream of IPTV with m3u8 parser in Swift - Atonomik<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to video stream of IPTV with m3u8 parser in Swift\" \/>\n<meta property=\"og:description\" content=\"We all know building an iOS application requires some UI and Swift knowledge. While creating many standard features, UI components are placed, then an interaction and business layer is created in accordance with the design pattern used. But there are some features that the algorithms should be used to play a key role.\u00a0IPTV\u00a0feature is one […]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\" \/>\n<meta property=\"og:site_name\" content=\"Atonomik\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/facebook.com\/atonomik\" \/>\n<meta property=\"article:published_time\" content=\"2023-01-13T07:49:20+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-05-08T22:24:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"640\" \/>\n\t<meta property=\"og:image:height\" content=\"405\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"Arif \u00c7a\u011flar\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@atonomik\" \/>\n<meta name=\"twitter:site\" content=\"@atonomik\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Arif \u00c7a\u011flar\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\"},\"author\":{\"name\":\"Arif \u00c7a\u011flar\",\"@id\":\"https:\/\/www.atonomik.com\/en\/#\/schema\/person\/8823a7897d2080c40679a08f84119e81\"},\"headline\":\"How to video stream of IPTV with m3u8 parser in Swift\",\"datePublished\":\"2023-01-13T07:49:20+00:00\",\"dateModified\":\"2023-05-08T22:24:51+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\"},\"wordCount\":638,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp\",\"articleSection\":[\"Medium\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\",\"url\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\",\"name\":\"How to video stream of IPTV with m3u8 parser in Swift - Atonomik\",\"isPartOf\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp\",\"datePublished\":\"2023-01-13T07:49:20+00:00\",\"dateModified\":\"2023-05-08T22:24:51+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage\",\"url\":\"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp\",\"contentUrl\":\"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp\",\"width\":640,\"height\":405},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/www.atonomik.com\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to video stream of IPTV with m3u8 parser in Swift\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.atonomik.com\/en\/#website\",\"url\":\"https:\/\/www.atonomik.com\/en\/\",\"name\":\"Atonomik\",\"description\":\"Software House\",\"publisher\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.atonomik.com\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.atonomik.com\/en\/#organization\",\"name\":\"Atonomik\",\"url\":\"https:\/\/www.atonomik.com\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.atonomik.com\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.atonomik.com\/wp-content\/uploads\/atonomik-footer-logo.png\",\"contentUrl\":\"https:\/\/www.atonomik.com\/wp-content\/uploads\/atonomik-footer-logo.png\",\"width\":598,\"height\":376,\"caption\":\"Atonomik\"},\"image\":{\"@id\":\"https:\/\/www.atonomik.com\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/facebook.com\/atonomik\",\"https:\/\/x.com\/atonomik\",\"https:\/\/www.instagram.com\/atonomikcom\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.atonomik.com\/en\/#\/schema\/person\/8823a7897d2080c40679a08f84119e81\",\"name\":\"Arif \u00c7a\u011flar\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.atonomik.com\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8ea4eca164a5d760dee4f0c8280b2bc39811380a10a078474581164f0f7aadf4?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8ea4eca164a5d760dee4f0c8280b2bc39811380a10a078474581164f0f7aadf4?s=96&d=mm&r=g\",\"caption\":\"Arif \u00c7a\u011flar\"},\"url\":\"https:\/\/www.atonomik.com\/en\/blog\/author\/arifcaglar\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How to video stream of IPTV with m3u8 parser in Swift - Atonomik","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/","og_locale":"en_US","og_type":"article","og_title":"How to video stream of IPTV with m3u8 parser in Swift","og_description":"We all know building an iOS application requires some UI and Swift knowledge. While creating many standard features, UI components are placed, then an interaction and business layer is created in accordance with the design pattern used. But there are some features that the algorithms should be used to play a key role.\u00a0IPTV\u00a0feature is one […]","og_url":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/","og_site_name":"Atonomik","article_publisher":"https:\/\/facebook.com\/atonomik","article_published_time":"2023-01-13T07:49:20+00:00","article_modified_time":"2023-05-08T22:24:51+00:00","og_image":[{"width":640,"height":405,"url":"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp","type":"image\/webp"}],"author":"Arif \u00c7a\u011flar","twitter_card":"summary_large_image","twitter_creator":"@atonomik","twitter_site":"@atonomik","twitter_misc":{"Written by":"Arif \u00c7a\u011flar","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#article","isPartOf":{"@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/"},"author":{"name":"Arif \u00c7a\u011flar","@id":"https:\/\/www.atonomik.com\/en\/#\/schema\/person\/8823a7897d2080c40679a08f84119e81"},"headline":"How to video stream of IPTV with m3u8 parser in Swift","datePublished":"2023-01-13T07:49:20+00:00","dateModified":"2023-05-08T22:24:51+00:00","mainEntityOfPage":{"@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/"},"wordCount":638,"commentCount":0,"publisher":{"@id":"https:\/\/www.atonomik.com\/en\/#organization"},"image":{"@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp","articleSection":["Medium"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/","url":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/","name":"How to video stream of IPTV with m3u8 parser in Swift - Atonomik","isPartOf":{"@id":"https:\/\/www.atonomik.com\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage"},"image":{"@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage"},"thumbnailUrl":"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp","datePublished":"2023-01-13T07:49:20+00:00","dateModified":"2023-05-08T22:24:51+00:00","breadcrumb":{"@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#primaryimage","url":"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp","contentUrl":"https:\/\/cdn.atonomik.com\/1_6DzJ_aHLSm-2MOEKPg1W6g.webp","width":640,"height":405},{"@type":"BreadcrumbList","@id":"https:\/\/www.atonomik.com\/en\/blog\/how-to-video-stream-of-iptv-with-m3u8-parser-in-swift\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/www.atonomik.com\/en\/"},{"@type":"ListItem","position":2,"name":"How to video stream of IPTV with m3u8 parser in Swift"}]},{"@type":"WebSite","@id":"https:\/\/www.atonomik.com\/en\/#website","url":"https:\/\/www.atonomik.com\/en\/","name":"Atonomik","description":"Software House","publisher":{"@id":"https:\/\/www.atonomik.com\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.atonomik.com\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.atonomik.com\/en\/#organization","name":"Atonomik","url":"https:\/\/www.atonomik.com\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.atonomik.com\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.atonomik.com\/wp-content\/uploads\/atonomik-footer-logo.png","contentUrl":"https:\/\/www.atonomik.com\/wp-content\/uploads\/atonomik-footer-logo.png","width":598,"height":376,"caption":"Atonomik"},"image":{"@id":"https:\/\/www.atonomik.com\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/facebook.com\/atonomik","https:\/\/x.com\/atonomik","https:\/\/www.instagram.com\/atonomikcom\/"]},{"@type":"Person","@id":"https:\/\/www.atonomik.com\/en\/#\/schema\/person\/8823a7897d2080c40679a08f84119e81","name":"Arif \u00c7a\u011flar","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.atonomik.com\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8ea4eca164a5d760dee4f0c8280b2bc39811380a10a078474581164f0f7aadf4?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8ea4eca164a5d760dee4f0c8280b2bc39811380a10a078474581164f0f7aadf4?s=96&d=mm&r=g","caption":"Arif \u00c7a\u011flar"},"url":"https:\/\/www.atonomik.com\/en\/blog\/author\/arifcaglar\/"}]}},"_links":{"self":[{"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/posts\/1306","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/comments?post=1306"}],"version-history":[{"count":2,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/posts\/1306\/revisions"}],"predecessor-version":[{"id":2789,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/posts\/1306\/revisions\/2789"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/media\/1309"}],"wp:attachment":[{"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/media?parent=1306"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/categories?post=1306"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.atonomik.com\/en\/wp-json\/wp\/v2\/tags?post=1306"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}