本文介绍了快速解析 get_video_info(YouTube 信息数据)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

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

To get a direct link to YouTube video I made request to get the get_video_info file, in this file that link, but I have to parse it, I find the solution to parse it by PHP but I want to parse it directly from my App

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

I get the data from my code like this:

        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 符号:

I got data with many Ascii symbols like this:

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%2C65%2C4C17C%2C1&安培; SSL = 1&安培; adaptive_fmts =类型%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550114115045036%26bitrate%3D16962786%26size%3D3840x2160%26index%3D221-1771%26quality_label%3D2160p%26xtags%3D%26url%3Dhttps%253A%252F%252Fr2---sn-nuj-wxqek.googlevideo.com%252Fvideoplayback%253Fexpire%253D15515002605%25m252525252525m252525252525m25m%25m253%25c5m253%2525c5m%2525c5m5c%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.557BCD34CEED4CEED4CEED4CEED6CEED69E2FD38%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%2526ipbits%253D0%2526毫米%253D31%25252C29%2526mn%253Dsn-NUJ-wxqek%25252Csn-hgn7yn7l%26clen%3D547103152%26init%3D0-220%26itag%3D313%26primaries%3Dbt709%26fps%3D30%2Ctype%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550113771564979%26bitrate%3D6318874%26size%3D2560x1440%26index%3D220-1763%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- ....分机

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%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550114115045036%26bitrate%3D16962786%26size%3D3840x2160%26index%3D221-1771%26quality_label%3D2160p%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%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%2526ipbits%253D0%2526mm%253D31%25252C29%2526mn%253Dsn-nuj-wxqek%25252Csn-hgn7yn7l%26clen%3D547103152%26init%3D0-220%26itag%3D313%26primaries%3Dbt709%26fps%3D30%2Ctype%3Dvideo%252Fwebm%253B%2Bcodecs%253D%2522vp9%2522%26eotf%3Dbt709%26projection_type%3D1%26lmt%3D1550113771564979%26bitrate%3D6318874%26size%3D2560x1440%26index%3D220-1763%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- .... ext

推荐答案

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

I find code can deal with this YouTube request, it created on 2015 so it can't run on the new Swift, so I edited it to work on Swift 4, just copy this code in side a new Swift file then call function h264videosWithYoutubeID(youtubeID: your TouTube ID) and you will get the correct 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"]))
            }
        }
    }
}
}

这篇关于快速解析 get_video_info(YouTube 信息数据)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-08 22:26