美文网首页
HLS付费点播(Vod)整套流程实现

HLS付费点播(Vod)整套流程实现

作者: WessonWu | 来源:发表于2020-04-01 19:32 被阅读0次

    1. 实验环境

    • 服务器环境:Mac + Php + Nginx (以我的环境)
    • 客户端:AVPlayer + AVAssetResourceLoader

    2. 服务端实现

    // private_key.php
    <?php
        $token = $_SERVER["HTTP_TOKEN"];
        // 检查是否授权等
        if ( $token == "test" ) {
            $file = "/Users/Shared/nginx/private/keys/test.key"; // key所在的目录或从数据库获取
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="'.basename($file).'"');
            header('Expires: 0');
            // header('Cache-Control: must-revalidate');
            header('Pragma: public');
            header('Content-Length: ' . filesize($file));
            readfile($file);    
        } else {
            http_response_code(401);
            header('Content-Type: application/json');
            echo json_encode([
                "code" => 99,
                "result" => NULL,
                "message" => "invalidate username and password"
            ]);
        }
    ?>
    
    # 在nginx的配置文件nginx.conf内的server块中添加以下配置
    rewrite ^/private/keys/(.+?).key$ /private_key.php last;
    location / {
        root   /Users/Shared/nginx/www;
        index  index.html index.htm index.php;
    }
    location ^~ /files {
        root    /Users/Shared/nginx/;
    }
    location ~ \.php$ {
        root         /Users/Shared/nginx/www;
        fastcgi_pass   127.0.0.1:9000;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /Users/Shared/nginx/www/$fastcgi_script_name;
        include        fastcgi_params;
    }
    

    客户端实现

    // ViewController.swift
    import UIKit
    import AVKit
    class ViewController: UIViewController {
        let dispatchQueue = DispatchQueue(label: "cn.wessonwu.demos.AVPlayDemo.resourceLoader")
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view.
        }
    
        @IBAction func onPlayPressed(_ sender: Any) {
            let vc = AVPlayerViewController()
            
            let urlAsset = AVURLAsset(url: URL(string: "http://localhost:8080/files/test.m3u8")!)
            urlAsset.resourceLoader.setDelegate(self, queue: dispatchQueue)
            
            let playerItem = AVPlayerItem(asset: urlAsset)
            vc.player = AVPlayer(playerItem: playerItem)
            self.present(vc, animated: true, completion: nil)
        }
        
        func shouldLoadOrRenewRequestedResource(_ loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
            guard let url = loadingRequest.request.url,
                url.pathExtension == "key" else {
                return false
            }
            let keyServerURL = url
            var request = URLRequest(url: keyServerURL)
            request.addValue("test", forHTTPHeaderField: "TOKEN") // 添加验证(该例子只用了简单的验证)
            URLSession.shared.dataTask(with: request) { (data, resp, error) in
                self.dispatchQueue.async {
                    if let ckcData = data {
                        loadingRequest.dataRequest?.respond(with: ckcData)
                        loadingRequest.contentInformationRequest?.contentType = AVStreamingKeyDeliveryContentKeyType
                        loadingRequest.finishLoading()
                    } else {
                        loadingRequest.finishLoading(with: error)
                    }
    
                }
            }
            .resume()
            return true
        }
        
    }
    
    extension ViewController: AVAssetResourceLoaderDelegate {
        func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForLoadingOfRequestedResource loadingRequest: AVAssetResourceLoadingRequest) -> Bool {
            return shouldLoadOrRenewRequestedResource(loadingRequest)
        }
        func resourceLoader(_ resourceLoader: AVAssetResourceLoader, shouldWaitForRenewalOfRequestedResource renewalRequest: AVAssetResourceRenewalRequest) -> Bool {
            return shouldLoadOrRenewRequestedResource(renewalRequest)
        }
    }
    

    Enjoy it!!!

    相关文章

      网友评论

          本文标题:HLS付费点播(Vod)整套流程实现

          本文链接:https://www.haomeiwen.com/subject/vnidoctx.html