Получение прямой ссылки на видео ВКонтакте.

Доброго времени суток.

Вот и у меня возникла необходимость получить прямую ссылку на видео Вконтакте. Статьи на эту тему в интернете есть, я написал эту опираясь на статью на сайте welinux.ru. Алгоритм получения ссылки там изложен, осталось перевести его в необходимый язык программирования.

Вот что у меня получилось:

function getVideoUrl($url) {
    $url =  str_replace("\/","/",$url);
    $ch = curl_init();
    $user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2.13) ' .
        'Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)';
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
    curl_setopt($ch, CURLOPT_HEADER,false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_VERBOSE,1);
    $result = curl_exec($ch);
    curl_close($ch);
    $video_url = '';
    $hd = Array('240', '360', '480', '720', '1080');
    preg_match("/var video_host = '([0-9a-z\.\/:]*)'/", $result, $res);
    if (preg_match('/http/', $res[1]))
        $video_url.=$res[1];
    else {
        $video_url.='http://cs' . $host[1];
    }
    if (substr($video_url, strlen($video_url) - 1, 1) != '/')
        $video_url.='/';
    preg_match("/var video_uid = '(\d*)'/", $result, $res);
    $video_url.='u' . $res[1] . '/video/';
    preg_match("/var video_vtag = '([\da-zA-Z]*)'/", $result, $res);
    $video_url.=$res[1];
    preg_match("/var video_no_flv = (\d)/", $result, $res);
    if ($res[1] == 0) {
        $video_url .= '.flv';
    }
    else if($res[1] == 1){
        preg_match("/var video_max_hd = '(\d)'/", $result, $res);
        $video_url .= '.'.$hd[$res[1]].'.mp4'.$res[1];
    }
    return $video_url;
}

Эта функция выдает прямую ссылку на видео ВКонтакте, не на плеер, а конкретно на само видео.

Но с недавнего времени видео можно подключать и из YouTube. Для этого я немножко изменил функцию (спасибо этой статье за подсказку в решении задачи; там есть некоторая неточность — вместо fmt_url_map необходимо использовать
url_encoded_fmt_stream_map):

function getVideoUrl($url) {
    $url =  str_replace("\/","/",$url);
    $ch = curl_init();
    $user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 6.0; ru; rv:1.9.2.13) ' .
        'Gecko/20101203 Firefox/3.6.13 ( .NET CLR 3.5.30729)';
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_USERAGENT, $user_agent);
    curl_setopt($ch, CURLOPT_HEADER, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
    curl_setopt($ch, CURLOPT_VERBOSE, 1);
    $result = curl_exec($ch);
    curl_close($ch);
    $video_url = '';
    $video_array = Array();
    $hd = Array('240', '360', '480', '720', '1080');
    preg_match("/var video_host = '([0-9a-z\.\/:]*)'/", $result, $res);
    if (preg_match('/http/', $res[1]))
        $video_url.=$res[1];
    else {
        $video_url.='http://cs' . $host[1];
    }
    if (substr($video_url, strlen($video_url) - 1, 1) != '/')
        $video_url.='/';
    preg_match("/var video_uid = '(\d*)'/", $result, $res);
    $video_url.='u' . $res[1] . '/video/';
    preg_match("/var video_vtag = '([\da-zA-Z]*)'/", $result, $res);
    $video_url.=$res[1];
    preg_match("/var video_no_flv = (\d)/", $result, $res);
    if ($res[1] == 0) {
        preg_match("/http:\/\/www\.youtube\.com\/embed\/([\w\s\-]+)/", $result, $res);
        if (strlen($res[1]) == 0) {
            $video_array[] = $video_url . '.flv';
        } else {
            $formats = array('18', '22', '37', '38');
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, 'http://www.youtube.com/get_video_info?video_id=' . $res[1]);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            $links = curl_exec($ch);
            curl_close($ch);
            parse_str($links, $info);
            if ($info["status"] == 'fail') {
                $video_array[] = '';
                return;
            }
            $res = explode(',', $info['url_encoded_fmt_stream_map']);
            foreach ($res as $k => $v) {
                parse_str($v, $rr);
                if (in_array($rr['itag'], $formats)) {
                    $video_array[] = $rr['url'];
                }
            }
        }
    } else if ($res[1] == 0) {
        $hd = Array('240', '360', '480', '720', '1080');
        preg_match("/var video_host = '([0-9a-z\.\/:]*)'/", $result, $res);
        if (preg_match('/http/', $res[1]))
            $video_url.=$res[1];
        else {
            $video_url.='http://cs' . $res[1];
        }
        if (substr($video_url, strlen($video_url) - 1, 1) != '/')
            $video_url.='/';
        preg_match("/var video_uid = '([0-9]*)'/", $result, $res);
        $video_url.='u' . $res[1] . '/video/';
        preg_match("/var video_vtag = '([0-9a-zA-Z]*)'/", $result, $res);
        $video_url.=$res[1];
        preg_match("/var video_max_hd = '([0-9]*)'/", $result, $res);
        for ($i = 0; $i <= $res[1]; $i++)
            $video_array[] = $video_url . '.' . $hd[$i] . '.mov';
    }
    return $video_array;
}

Эта функция уже выдает не только ссылки на видео ВКонтакте, но и ссылки на видео, размещенное из YouTube. Все видео-файлы мне было необходимо получать в mp4, а то что Контакт выдает и flv — это лирическое отступление. В приведенной выше статье на тему видео YouTube есть массив со всеми форматами и расширениями, если кому будет необходимо получить другие форматы.

P.S. Если кто заметит неточность или ошибку — не серчайте, лучше напишите что и где не работает, а я буду рад поправить. Но перед публикацией код был проверен.

P.S.S. Расширение видео-файлов сменилось. Теперь система выдает MOV. Почитайте комменты, если у Вас не находит файл по ссылке, которую сгенерировала функция.



8 Комментарии

  • Денис

    А можно пример скрипта? Что-то никак не получается…

    • Что конкретно не получается и какую ссылку на плеер используете? Ссылка имеет примерно такой формат «http:\/\/vkontakte.ru\/video_ext.php?oid=2832967&id=161867304&hash=227459aa2e25b14b». Со слэшами не перебор — в итоге они преобразуются как надо. Вот эту ссылку и надо передавать в любую из этих функций как параметр. Такую ссылку дает функция ВКонтакте.API video.get(), параметр player в возвращаемом результате. Подробнее о функции здесь.

  • Денис
    $url = 'http:\/\/vkontakte.ru\/video_ext.php?oid=2832967&amp;id=161867304&amp;hash=227459aa2e25b14b';
    $url2 = getVideoUrl ($url);
    echo $url2;
    
    • Спасибо за комментарии. Нашел недочет в коде благодаря Вам :) Использую это в одном проекте, но там это все в ООП и эту функцию собирал отдельно. В начало надо добавить $url = str_replace(«\/»,»/»,$url); чтобы лишние слэши удалялись. Слова про то, что «со слэшами не перебор» беру назад.
      Кстати для нормального вывода информации, полученной этими функциями лучше использовать var_dump($url2);

  • Кирилл

    че то неправельную ссылку выдает функция.

    • Боюсь что ВКонтакте поменяли что-то в системе выдачи видео файлов. Проверил сейчас скрипт на трех разных хостигах и плюс на локальном сервере — переменная vtag в теле плеера, которая отвечает за идентификацию видео-файла (я так думаю), на каждом сервере была разная. Но при обновлении страницы не менялась, значит скорее всего привязана каким то образом к данным заголовка. У меня такое впечатление что тут важен IP-адрес с которого был запрос. Вот как то так )
      Плюс судя по файлу, который обрабатывает и выдает видео, http://vkontakte.ru/js/video_html5.js, они поменяли и расширение файлов на MOV. Раньше было MP4.
      Здесь можете посмотреть например какой код выдает код на хостинге этого сайта.

  • Евген

    Как сделать так что бы сначало скрипт получал ИП пользователя который нажал на Play в плеере Uppod и на его ип был сгенерирован vtag и отсылалось ему… (Это я к тому что бы не было ретонсляции, ну видео на хостинг не загружался)

  • Добавить комментарий

    Ваш e-mail не будет опубликован. Обязательные поля помечены *

    Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

    Яндекс.Метрика