Pull to refresh

Comments 20

Можно было так не усложнять, и пока-что есть возможность из ссылки на файл m3u8 получить ссылку на mp3.
m3u8 воспроизводят и VLC и несколько десятков других популярных плееров (включая, кажется, даже стандартный проигрыватель windows)
m3u/m3u8 использовался как стандарт для плейлистов winamp-а еще в далеких нулевых, если ничего не путаю

В мобильной версии сайта выдаются ссылки на mp3.

Вообще во многих мобильных версиях чего угодно допускаются всяческие поблажки в "безопасности". Взять тот же авито, который прячет номер телефона в картинке в обычной версии сайта. Но в мобильной эта картинка внезапно становится ссылкой с "href=tel:...". На юле, кажется, тоже самое, но точно не помню. Думаю у каждого найдется ещё по примеру подобных вещей.

Попробуйте такой вариант с ffmpeg:


ffmpeg -i https://example.org/stream.m3u8 -c copy out.ts

Ну а если нужен mp3 то выше уже подсказали как его получить.

Писал своё приложение для загрузки этих вот потоковых m3u8-ts, но с аудио вк возник затык с тем, чтобы из ts перегнать в mp3 без пережатия. FFmpeg отказывается это делать.
я конвертировал это с помощью vlc media pleyer'a
Как это сделать без перекодирования?

В ts звук вроде кодируется в AAC поэтому в mp3 без перекодирования не перегнать.

Вроде бы контейнер не накладывает ограничений на формат сжатия содержимого.
Mediainfo про ts, скачанные с вк, говорит, что внутри mp3.

Надо смотреть что пишет ffmpeg. Провёл эксперимент. Загнал mp3 в ts и обратно в mp3 без перекодирования (-c copy). Всё нормально прошло.

Да, мой косяк. Но всё интереснее на самом деле. Я проверял на одном треке и не обратил внимание, что скачанный ts толком не проигрывается, один скрежет. Попробовал скачать другие — всё хорошо, и ffmpeg в mp3 их перегоняет без вопросов.
В чем же разница? А в том, что у первого в m3u8 перед половиной фрагментов идёт строчка
#EXT-X-KEY:METHOD=AES-128,URI="https://psv4.vkuseraudio.net/c521401/u26908367/ad39a2fde/audios/595ebdc0ccd6/key.pub?extra=bqGmxzhqMNM8OyEz93EpIygTSFPBPGmJTRHCGQg_b6IGBFTRLAdQlqCRpyEne_OOklLhA4nT5xhefbCh29ACP1bkfOl4Nwwc24qCEdELbZt1oK2NgIhZz-LNSDIuXSPqxf5256HuVwrJDlx2a_0" (по ссылке файл с ключом)
А перед второй половиной #EXT-X-KEY:METHOD=NONE
Судя по всему половина фрагментов шифруется. Причем с чередованием, один фрагмент шифрованный, следующий нет.
А есть какая-то библиотека для расшифровки AES-128 с помощью файла ключа? А то вдруг эту «фичу» с вытаскиванием mp3 уберут, хотелось бы сделать более надёжное решение.

На самом деле, там ещё нужна перепаковка, если мы хотим из ts mp3 получить, как я понял, почитав статью на Вики.

Но у меня проблемы возникли ещё раньше: почему-то при попытке создать Blob из массива других Blob-ов с целью склеить фрагметы потока получается какая-то шляпа очень маленького размера в 1,65 Кб (хотя это совершенно штатная возможность, если верить документации и StackOverflow). Каждый фрагмент трека, если что, весит 127-130 Кб, поэтому я вообще в душе не понимаю, что происходит.

Вот мой код если что
if (url.match(/\.m3u8$/)) {
    var xhr = new XMLHttpRequest()
    xhr.open('GET', url, true)
    xhr.onload = function() {
        var data = xhr.responseText.split(/\n/)
        var base = ''
        var parts = []
        var p = []
        data.forEach(function(el) {
            var m = el.match(/URI="([^"]+)"/)
            if (m) {
                base = m[1].split(/\//).slice(0, -1).join('/')
            } else {
                m = el.match(/\.ts\??/)
                if (m) parts.push(el.slice(0, -1))
            }
        })
        //console.log(base)
        function fetchNext() {
            var req = new XMLHttpRequest()
            req.open('GET', base + '/' + parts[index], true)
            req.responseType = 'blob'
            req.onload = function() {
                p[index] = req.response
                index++
                //console.log(req.response)
                if (index < parts.length) fetchNext()
                else saveStream()
            }
            req.send(null)
        }

        var index = 0
        fetchNext()

        function saveStream() {
            var blob = new Blob(parts, {type : 'audio/m2ts'})
            var url = URL.createObjectURL(blob)
            var a = document.createElement('a')
            a.download = getFileName().split('.')[0] + '.ts'
            a.href = url
            document.body.appendChild(a)
            a.click()
            document.body.removeChild(a)
        }
    }
    xhr.send(null)
}

А в чем смысл? Любое расширение браузера спокойно скачивает в mp3.

Смысл в том, чтобы незнающие люди поняли, КАК эти расширения работают
>P.P.S. Забыл сказать, что яндекс.браузер до сих пор возвращает ссылки на .mp3)

Я дебажил код и это зависит от UserAgent параметра в HTTP header. Тоесть если вы поставите такойже как у яндекс.браузера то будет возвращать тоже mp3 ссылку, но думаю это временное решение так я делал эмулируя FireFox и спустя неделю это перестало работать и стали приходить ссылки m3u8 так что скорее всего и для яндекс.браузера скоро будут m3u8.

Я вот не могу понять две вещи
1) если я правильно понимаю этот m3u8 указывает на аудиофайл разделенный на куски. В каком формате этот файл? в mp3 или чтото другое? Как соберать файл по этим кускам?

2) ктото понял что за шифрование AES-128? там первым параметром приходит какойто ключ и ко всем последующим ссылкам которые есть в m3u8 добавляються около 60 символов видимо это и есть защита сайта.
Там MPEG-TS audio stream. Кодек — всё тот же MP3, только цельный файл разбит по сегментам длиной примерно 2 секунды (первый сегмент трека около 5-6 секунд). При этом сегменты ещё и шифруются ключом по алгоритму AES-128 (иногда не все, а только часть, примерно половина). Декодирование делает сам браузер под капотом — в этом и проблема, иначе можно было бы просто сохранить в массив массивов все сегменты и сделать склейку с выводом в файл через диалог.

Это из того, что я смог сам определить методом тыка.
Sign up to leave a comment.

Articles