Расшифровка подписки YouTube с помощью рабочего примера для VB.Net

Я знаю, что есть много проектов, и я мог бы их использовать. Но я действительно хочу, чтобы он работал без зависимостей в моем проекте VB.Net.

Итак, я пытаюсь создать Youtube загрузчик. Он отлично работает на обычных видео. Но эти специальные видео, такие как Vevo (https://www.youtube.com/watch?v=9bZkp7q19f0), а некоторые другие не работают.

У них есть другая подпись, которую мне нужно расшифровать. Здесь мне нужен JS файл HTMLPlayer, который я смог извлечь (http://s.ytimg.com/yts/jsbin/html5player-de_DE-vflG4uS_k/html5player.js). И в этом файле мне нужно найти специальную функцию и посмотреть, что она делает, а затем сделать то же самое в моем коде. До сих пор так легко, но на некоторых примерах я даже не смог найти "sig =" или "signature =", и когда я их нашел, это действительно не помогло мне.

Итак, я хотел бы знать, как я могу извлечь необходимую информацию из файла html5.player.js. Итак, как вы можете видеть здесь https://superuser.com/info/773719/how-do-all-of-these-save-video-from-youtube-services-work У меня есть эта ссылка на этот файл.

Я также нашел этот https://mytoolkit.codeplex.com/discussions/479171, который помог мне начать. Но с самого начала Sign_Decipher я не нахожу такую ​​вызываемую функцию в файле js.

Некоторые другие ссылки, которые я нашел, но не помогли мне запустить его или просто слишком стары:

Некоторые API, которые также не работают:

Ответ 1

Связанные веб-сайты, которые вы предоставили, уже содержат все, что вам нужно знать для решения этой проблемы. Большая часть работы может быть выполнена с помощью простых регулярных выражений. Это необходимые шаги для декодирования такой скремблированной подписи:

  • Загрузите html5player.js, который используется на странице видео, которое вы хотите загрузить.
  • Определите имя функции, которая используется для декодирования закодированной подписи.
  • Используя это имя, извлеките определение функции из script.
  • Запустите извлеченную функцию в JS-интерпретаторе и просто расшифруйте подпись с ней.

Получение html5player.js

Первый шаг не должен быть проблемой, как вы уже это сделали. Большинство URL script всегда будут одинаковыми (https://s.ytimg.com/yts/jsbin/html5player-VERSION/html5player.js). Время от времени изменяется только часть версии (например, de_DE-vflR89yTY). Это означает, что вам просто нужно найти версию script на видеостранице и адаптировать по умолчанию script URL. В результате URL-адрес будет выглядеть примерно так: https://s.ytimg.com/yts/jsbin/html5player-de_DE-vflR89yTY/html5player.js

Версия игрока: html5player-([\w\d\-]+)\\\/html5player\.js

Версия может быть найдена в первой группе захвата.

Извлечение функции декодирования

Прежде чем мы сможем извлечь функцию, мы должны знать ее имя. К сожалению, имя decode-funtion может меняться от версии к версии, но часть кода, использующего эту функцию, обычно не изменяется.

Имя функции декодирования: \.sig\|\|([a-zA-Z0-9$]+)\(

Имя функции будет в первой группе захвата.

Теперь, когда мы знаем имя, мы можем извлечь эту функцию, снова используя regex. Просто замените # NAME # на имя функции.

Определение декодированной функции: function #NAME#\([^\)]+\){.*?};


Помимо фактической декодированной функции нам нужно извлечь некоторые служебные функции, которые использует функция декодирования. Эти функции содержатся в объекте. Прежде чем мы сможем извлечь определение объекта из html5player.js, мы должны определить имя объекта.

Не забудьте использовать извлеченное определение функции в качестве ввода для регулярного выражения на этот раз.

Имя объекта-помощника: ;([A-Za-z0-9]+)\.

Имя объекта будет в первой группе захвата.

Используя имя объекта и некоторое регулярное выражение, мы можем извлечь определение объекта из player- script так же, как мы это сделали с определением функции раньше. Замените # NAME # на имя объекта с последнего шага.

Определение вспомогательного объекта: var #NAME#={.*?};

Теперь у нас есть все необходимое для восстановления скремблированной подписи.

Декодирование подписи

Последний шаг - использовать извлеченные функции для декодирования подписи. Чтобы выполнить это в .NET, мы должны проанализировать и выполнить код JavaScript. К счастью, есть готовые к использованию решения, которые могут сделать это для нас. Одним из них является интерпретатор JS Jint. Другой вариант - использовать один из Script Двигатели, доступные в Windows. Simon Mourier предоставляет удобную оболочку вокруг этих движков в следующем ответе: fooobar.com/questions/32399/...


Вот небольшая примерная программа, которая объединяет все вышеописанные шаги и использует оболочку Simon для декодирования первой подписи, которую она может найти на жестко закодированной странице видео, и печатать как закодированные, так и декодированные подписи на консоли.

Код написан на С#, но его легко преобразовать в VB.NET.

class Program
{
    private const string PlayerScriptUrlTemplate = "https://s.ytimg.com/yts/jsbin/html5player-{0}/html5player.js";
    private const string DecodeFunctionPatternTemplate = @"function #NAME#\([^\)]+\){.*?};";
    private const string HelperObjectPatternTemplate = @"var #NAME#={.*?};";

    private static readonly Regex SignatureRegex = new Regex(@"s=(?<Signature>[A-F0-9]+\.[A-F0-9]+)");
    private static readonly Regex PlayerVersionRegex = new Regex(@"html5player-(?<PlayerVersion>[\w\d\-]+)\\\/html5player\.js");
    private static readonly Regex DecodeFunctionNameRegex = new Regex(@"\.sig\|\|(?<FunctionName>[a-zA-Z0-9$]+)\(");
    private static readonly Regex HelperObjectNameRegex = new Regex(@";(?<ObjectName>[A-Za-z0-9]+)\.");

    static void Main()
    {
        const string videoUrl = "https://www.youtube.com/watch?v=6pIyg35wiB4";

        var client = new WebClient();
        var videoPageData = client.DownloadString(videoUrl);

        var encodedSignature = SignatureRegex.Match(videoPageData).Groups["Signature"].Value;

        var playerVersion = PlayerVersionRegex.Match(videoPageData).Groups["PlayerVersion"].Value;
        var playerScriptUrl = string.Format(PlayerScriptUrlTemplate, playerVersion);
        var playerScript = client.DownloadString(playerScriptUrl);

        var decodeFunctionName = DecodeFunctionNameRegex.Match(playerScript).Groups["FunctionName"].Value;
        var decodeFunction = Regex.Match(playerScript, DecodeFunctionPatternTemplate.Replace("#NAME#", decodeFunctionName)).Value;
        var helperObjectName = HelperObjectNameRegex.Match((decodeFunction)).Groups["ObjectName"].Value;
        var helperObject = Regex.Match(playerScript, HelperObjectPatternTemplate.Replace("#NAME#", helperObjectName)).Value;

        var engine = new ScriptEngine(ScriptEngine.JavaScriptLanguage);
        var decoderScript = engine.Parse(helperObject + decodeFunction);
        var decodedSignature = decoderScript.CallMethod(decodeFunctionName, encodedSignature).ToString();

        // Jint variant
        //var engine = new Engine();
        //var decoderScript = engine.Execute(helperObject).Execute(decodeFunction);
        //var decodedSignature = decoderScript.Invoke(decodeFunctionName, encodedSignature).ToString();

        Console.WriteLine("Encoded Signature\n{0}.\n{1}", encodedSignature.Split('.').First(), encodedSignature.Split('.').Last());
        Console.WriteLine();
        Console.WriteLine("Decoded Signature\n{0}.\n{1}", decodedSignature.Split('.').First(), decodedSignature.Split('.').Last());
        Console.ReadLine();
    }
}

Ответ 2

Извините, но старый плеер "html5player.js" больше не работает, он 404, а URL теперь вам больше нравится https://s.ytimg.com/yts/jsbin/player-en_US-vfl_cdzrt/base.js

вы начинаете для шести, находите функцию, которая выглядит так в javascript

xr=function(a)
{
a=a.split("");
wr.rF(a,54);
wr.fs(a,75);
wr.N0(a,1);
wr.rF(a,52);
wr.N0(a,3);
wr.fs(a,31);
wr.rF(a,16);
wr.fs(a,38);
return a.join("")
}

После этого я немного теряюсь, потому что код для функции wr выглядит так же, и я не могу найти код для подкачки, замены, разделения функций, таких как Youtube, которые использовались в прошлом.

wr=function(a)
{
a=a.split("");
wr.rF(a,54);
wr.fs(a,75);
wr.N0(a,1);
wr.rF(a,52);
wr.N0(a,3);
wr.fs(a,31);
wr.rF(a,16);
wr.fs(a,38);
return a.join("")
}

wr.N0, я думаю, выглядит так, но javascript затем выходит за рамки моей зарплаты для меня, чтобы следить за тем, что происходит.

N0=function(a,b){Tb(nga,b)&&tm(H_(a),a.O,b,a.Pq,a)}