【问题标题】:Parsing get_video_info (YouTube information data) in swift快速解析 get_video_info(YouTube 信息数据)
【发布时间】:2019-07-23 23:44:58
【问题描述】:

为了获得指向 YouTube 视频的直接链接,我请求获取 get_video_info 文件,在这个文件中链接,但我必须解析它,我找到了通过 PHP 解析它的解决方案,但我想直接从我的应用

我像这样从我的代码中获取数据:

        let youtubeContentID = "sZz7tiToK1U"
    if let infoURL = URL(string:"https://www.youtube.com/get_video_info?video_id=\(youtubeContentID)") {
        let request = URLRequest(url: infoURL)
        let session = URLSession(configuration: .default)
        let task = session.dataTask(with: request, completionHandler: { (data, response, error) -> Void in
            if let error = error {
                print(error)
            } else if let data = data, let result = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {

               print(result)

            }
        })
        task.resume()
    }
}

我得到了很多像这样的 Ascii 符号的数据:

c=WEB&vss_host=s.youtube.com&innertube_api_version=v1&xhr_apiary_host=youtubei.youtube.com&apiary_host_firstparty=&status=ok&t=1&enabled_engage_types=3%2C6%2C4%2C5%2C17%2C1&ssl=1&adaptive_fmts=type%3Dvideo%252Fwebm%253B%2 %253d%25222%2522%26eotf%3dbt709%26propper_type%3D1%2610303036%26柠檬酸%3D16962786%26size%3d3840x2160%26.quitex%3d221-1771%26quality_label%3d2160p%26xtags%3D%26%260url%3dhttp%253a%252f%252fr2 --- sn-nuj-wxqek.googlevideo.com%252Fvideoplayback%253Fexpire%253D1551500605%2526usequic%253Dno%2526gir%253Dyes%2526mime%253Dvideo%25252Fwebm%2526requiressl%253Dyes%2526keepalive%253Dyes%2526fvip%253D2%2526clen%253D547103152%2526source %253Dyoutube%2526aitags%253D133%25252C134%25252C135%25252C136%25252C137%25252C160%25252C242%25252C243%25252C244%25252C247%25252C248%25252C271%25252C278%25252C313%25252C394%25252C395%25252C396%25252C397%2526signature%253D9C28A5C103FA95701CD3655795DDB7F2C0954828.55534AC9C7BEE5D644C3A34C2CD4A4EEC9E2FD38%2526lmt%253D1550114115045036 %2526ip%253D129.208.30.232%2526key%253Dyt6%2526c%253DWEB%2526ei%253D3bB5XKeFFNWd1wbBpqjgAg%2526txp%253D5531432%2526id%253Do-AIOVogCB8KFe32o_VgxSx-LqaEjNBZxiZ1jl81VTXZhF%2526sparams%253Daitags%25252Cclen%25252Cdur%25252Cei%25252Cgir%25252Cid%25252Cinitcwndbps%25252Cip %25252Cipbits%25252Citag%25252Ckeepalive%25252Clmt%25252Cmime%25252Cmm%25252Cmn%25252Cms%25252Cmv%25252Cpl%25252Crequiressl%25252Csource%25252Cusequic%25252Cexpire%2526initcwndbps%253D296250%2526itag%253D313%2526ms%253Dau%25252Crdu%2526mt%253D1551478917%2526mv%253Dm %2526dur%253d428.933%2526pl%253d19%2526厘米253d0%2526mm%253d31%2526mm29%2526mn%253dsn-nuj-wxqek%25252csn-hgn7yn7l%26clen%3d547103152%26,%3d0-220%26itag%3d313%26primaries%3dbt709 %26FPs%3D30%2倍键%3DVideo%252FBM%253b%253b%2bcodecs%253d%2522vp9%2522%26eotf%3dbt709%26propper_type%3d1%26lmt%3d155012%26size%3d20-11440%26,3d220-11440%26quality%3d220-1740%26quality_label%3d1440p %26xtags%3D%26url%3Dhttps%253A%252F%252Fr2---sn-nuj-wxqek.googlevideo.com %252Fvideoplayback%253Fexpire%253D1551500605%2526usequic%253Dno%2526gir%253Dyes%2526mime%253Dvideo%25252Fwebm%2526requiressl%253Dyes%2526keepalive%253Dyes%2526fvip%253D2%2526clen%253D155020170%2526source%253Dyoutube%2526aitags%253D133%25252C134%25252C135%25252C136 %25252C137%25252C160%25252C242%25252C243%25252C244%25252C247%25252C248%25252C271%25252C278%25252C313%25252C394%25252C395%25252C396%25252C397%2526signature%253D4D7BF761EE4A6DFD048DE3D48550FCE80E61B7D0.D625BCC9645471ABA478F79C197B2208F354E15F%2526lmt%253D1550113771564979%2526ip%253D129.208.30.232%2526key%253Dyt6 %2526c%253DWEB%2526ei%253D3bB5XKeFFNWd1wbBpqjgAg%2526txp%253D5531432%2526id%253Do-AIOVogCB8KFe32o_VgxSx- ....分机

【问题讨论】:

    标签: swift parsing youtube


    【解决方案1】:

    我发现代码可以处理这个 YouTube 请求,它创建于 2015 年,因此无法在新的 Swift 上运行,所以我对其进行了编辑以在 Swift 4 上运行,只需将此代码复制到一个新的 Swift 文件中,然后调用函数 h264videosWithYoutubeID(youtubeID: your TouTube ID) 你会得到正确的 url:

    import UIKit
    
    public extension NSURL {
    
    func dictionaryForQueryString() -> [String: AnyObject]? {
        if let query = self.query {
            return query.dictionaryFromQueryStringComponents()
        }
    
    
        let result = absoluteString?.components(separatedBy: "?")
        if result!.count > 1 {
            return result!.last?.dictionaryFromQueryStringComponents()
        }
        return nil
    }
    }
    
    public extension NSString {
    
    func stringByDecodingURLFormat() -> String {
        let result = self.replacingOccurrences(of: "+", with: " ")
        return result.removingPercentEncoding!
    }
    
    func dictionaryFromQueryStringComponents() -> [String: AnyObject] {
        var parameters = [String: AnyObject]()
        for keyValue in components(separatedBy: "&") {
            let keyValueArray = keyValue.components(separatedBy: "=")
            if keyValueArray.count < 2 {
                continue
            }
            let key = keyValueArray[0].stringByDecodingURLFormat()
            let value = keyValueArray[1].stringByDecodingURLFormat()
            parameters[key] = value as AnyObject
        }
        return parameters
    }
    }
    
    public class YoutubeUrlReciver: NSObject {
    static let infoURL = "http://www.youtube.com/get_video_info?video_id="
    static var userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_2)  AppleWebKit/537.4 (KHTML, like Gecko) Chrome/22.0.1229.79 Safari/537.4"
    
    public static func youtubeIDFromYoutubeURL(youtubeURL: NSURL) -> String? {
        if let
            youtubeHost = youtubeURL.host,
            let youtubePathComponents = youtubeURL.pathComponents {
            let youtubeAbsoluteString = youtubeURL.absoluteString
            if youtubeHost == "youtu.be" as String? {
                return youtubePathComponents[1]
            } else if youtubeAbsoluteString?.range(of: "www.youtube.com/embed") != nil {
                return youtubePathComponents[2]
            } else if youtubeHost == "youtube.googleapis.com" ||
                youtubeURL.pathComponents!.first == "www.youtube.com" as String? {
                return youtubePathComponents[2]
            } else if let
                queryString = youtubeURL.dictionaryForQueryString(),
                let searchParam = queryString["v"] as? String {
                return searchParam
            }
        }
        return nil
    }
    
    public static func h264videosWithYoutubeID(youtubeID: String) -> [String: AnyObject]? {
        let urlString = String(format: "%@%@", infoURL, youtubeID) as String
        let url = NSURL(string: urlString)!
        let request = NSMutableURLRequest(url: url as URL)
        request.timeoutInterval = 5.0
        request.setValue(userAgent, forHTTPHeaderField: "User-Agent")
        request.httpMethod = "GET"
        var responseString = NSString()
        let session = URLSession(configuration: URLSessionConfiguration.default)
        let group = DispatchGroup()
        group.enter()
        session.dataTask(with: request as URLRequest, completionHandler: { (data, response, _) -> Void in
            if let data = data as NSData? {
                responseString = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)!
            }
            group.leave()
        }).resume()
        group.wait()
        let parts = responseString.dictionaryFromQueryStringComponents()
        if parts.count > 0 {
            var videoTitle: String = ""
            var streamImage: String = ""
            if let title = parts["title"] as? String {
                videoTitle = title
            }
            if let image = parts["iurl"] as? String {
                streamImage = image
            }
            if let fmtStreamMap = parts["url_encoded_fmt_stream_map"] as? String {
                // Live Stream
                if let _: AnyObject = parts["live_playback"]{
                    if let hlsvp = parts["hlsvp"] as? String {
                        return [
                            "url": "\(hlsvp)" as AnyObject,
                            "title": "\(videoTitle)" as AnyObject,
                            "image": "\(streamImage)" as AnyObject,
                            "isStream": true as AnyObject
                        ]
                    }
                } else {
                    let fmtStreamMapArray = fmtStreamMap.components(separatedBy: ",")
                    for videoEncodedString in fmtStreamMapArray {
                        var videoComponents = videoEncodedString.dictionaryFromQueryStringComponents()
                        videoComponents["title"] = videoTitle as AnyObject
                        videoComponents["isStream"] = false as AnyObject
                        return videoComponents as [String: AnyObject]
                    }
                }
            }
        }
        return nil
    }
    public static func h264videosWithYoutubeURL(youtubeURL: NSURL,completion: ((
        _ videoInfo: [String: AnyObject]?, _ error: NSError?) -> Void)?) {
        DispatchQueue.global().async {
            if let youtubeID = self.youtubeIDFromYoutubeURL(youtubeURL: youtubeURL), let videoInformation = self.h264videosWithYoutubeID(youtubeID: youtubeID) {
                DispatchQueue.main.async {
                    completion?(videoInformation, nil)
                }
            }else{
                DispatchQueue.main.async {
                    completion?(nil, NSError(domain: "com.player.youtube.backgroundqueue", code: 1001, userInfo: ["error": "Invalid YouTube URL"]))
                }
            }
        }
    }
    }
    

    【讨论】:

    • 嗨 @nayef 这个例子能够从 youtube 中提取所有类型的视频
    猜你喜欢
    • 2016-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 2013-11-16
    • 2010-09-12
    相关资源
    最近更新 更多