Há alguns dias, ficou disponĂvel um concerto raro de um artista que muito aprecio (Jan Blomqvist), num conhecido site televisivo internacional.
O concerto sĂł ia estar disponĂvel 7 dias e nĂŁo existia um botĂŁo de download. Se quisesse ficar com ele no disco, tinha 2 soluções:
- gravar o ecrã e o áudio;
- encontrar uma forma de descarregar o ficheiro original do stream.
A primeira opção Ă© válida, mas nĂŁo sĂł ficaria com o computador indisponĂvel durante os 65 minutos do concerto, como nĂŁo sabia a resolução nativa do vĂdeo para ficar com a gravação no formato ideal.
A segunda ideia era bastante mais geek e provavelmente mais morosa, mas produziria um ficheiro “perfeito”. O desafio era bem mais interessante, portanto foi este o caminho escolhido.
Ao todo foram 4 passos, que em princĂpio poderás replicar noutros sites quando quiseres descarregar um stream para o teu computador. Dependendo da forma como o site apresenta os streams, talvez tambĂ©m tenhas sorte!
Vou tentar ser o mais descritivo possĂvel, mas convĂ©m estares minimamente confortável com o terminal e com o inspetor de um browser (como as DevTools do Google Chrome) para acompanhares este artigo.
Passo #1: Usar o painel Network das Chrome DevTools para encontrar os fragmentos do stream
Um stream raramente Ă© um ficheiro Ăşnico, com o vĂdeo completo; o conteĂşdo está habitualmente dividido num conjunto de fragmentos.
Isto Ă© conveniente para quem está a assistir ao stream, porque nĂŁo tem que esperar que o ficheiro completa seja descarregado se sĂł quiser assistir a umas partes especĂficas do vĂdeo. Para quem aloja o vĂdeo, isto tambĂ©m significa que pode poupar um pouco na conta do hosting no final do mĂŞs.
As 2 partes ganham – mas no nosso caso, vamos precisar de encontrar todos esses fragmentos.
No Google Chrome, se abrires as Chrome Dev Tools (basta carregar no botĂŁo direito do rato e fazer “Inspect” algures na página que tem o vĂdeo que pretendes), terás uma tab de nome “Network”. Tudo o que naquela página está a ser descarregado pelo teu browser Ă© apresentado ali.
Podes filtrar por tipos de ficheiro, como JS, CSS ou Imagens. Para streams, é boa ideia filtrar por “XHR”.
No caso deste concerto, podes ver que os ficheiros cumprem um padrĂŁo: segmentxx_1.av.ts
, onde xx
Ă© o nĂşmero do fragmento. Habitualmente, Ă© assim que estĂŁo repartidos.
Avançando atĂ© ao final do vĂdeo no leitor, vejo que no caso do meu vĂdeo, o Ăşltimo segmento tem o nĂşmero 392.
Temos então 392 fragmentos para descarregar. Para encontrares o URL, basta clicares num segmento com o botão direito do rato e escolher “Copy > Copy Link Address”.
Passo #2: Criar uma lista com todos os segmentos
O URL vai ser igual para os 392 fragmentos, mas o nĂşmero do ficheiro vai mudar. Precisamos entĂŁo de criar uma lista.
Há várias maneiras de chegar a este documento. No fundo, apenas precisamos de algo que repita o URL mas que acrescente +1 ao número do segmento.
Isto pode ser conseguido com Excel, com um editor de texto como o SublimeText com um plugin como o Text Pastry, ou por exemplo com JavaScript.
Para este caso, foi precisamente esta última opção que usei. Com um bom e velho loop, problema resolvido.
Assim sendo, nas DevTools podemos passar da aba “Network” para “Console” e colocar um código JS deste género:
// O número total de fragmentos fica nesta variável - no meu caso, 392
const length = 392;
// O URL que obtiveste com o "Copy Link Address" vai para esta variável, em forma de string - deves remover o nome do ficheiro, ou seja, o segmentxx_1.av.ts
const baseUrl = 'https://ositedoconcerto.com/pasta/outrapasta/'
// Criamos uma função com um loop para acrescentar o número ao segmento
function getURL() {
for (let index = 1; index < length; index++) {
const url = baseUrl +segment${index}_1_av.ts
console.log(url);
}
}
// Corremos a função, para que nos apresente a lista completa
getURL();
Passo #3: Descarregar todos os segmentos
Agora que temos a lista com o URL de todos os segmentos, podemos usar algum tipo de download manager para descarregar cada um, ou usar o terminal.
Sou grande fã do terminal para ações deste tipo e optei por recorrer ao wget para descarregar todos os ficheiros. Também poderás optar pelo curl (que podes utilizar em qualquer terminal), se preferires.
Para o caso do wget, basta editar a função que usámos no passo anterior, para o seguinte (a alteração é só dentro do console.log()
):
// Criamos uma função com um loop para acrescentar o número ao segmento
function getURL() {
for (let index = 1; index < length; index++) {
const url = baseUrl +segment${index}_1_av.ts
console.log("wget " + url);
}
}
Voltamos a correr o código completo nas DevTools e abrimos o terminal para colar a nova lista obtida de ficheiros a descarregar, já com o comando wget inserido por nós para as 392 ocasiões.
Passo #4: Juntar todos os segmentos
Agora que temos o nosso computador com todos os segmentos descarregados, está na altura de os juntar todos num sĂł vĂdeo.
Para isso, vamos voltar a usar o terminal, e o poderoso FFmpeg. Esta Ă© uma solução incrĂvel para manipular vĂdeo e atĂ© áudio, e Ă© claramente mais rápida que um programa como o Adobe Premiere ou o Final Cut.
Com o concat
do FFmpeg, Ă© fácil juntar uma enorme quantidade de vĂdeos.
O comando mágico a utilizar é o seguinte: ffmpeg -f concat -i segmentlist.txt -c copy all.ts
Como podes ver, o concat
recebe uma lista de ficheiros, vinda de um TXT que dei o nome de segmentlist.txt
.
O ficheiro TXT terá que ter o seguinte aspecto:
file 'segment1_1_av.ts'
file 'segment2_1_av.ts'
file 'segment3_1_av.ts'
file 'segment4_1_av.ts'
file 'segment5_1_av.ts'
E assim sucessivamente. Novamente, podes utilizar várias soluções para gerar esta lista, da mesma forma que no passo #2.
Vamos voltar entĂŁo a recorrer ao JavaScript e inserir o seguinte na consola:
const length = 392;
function getFileList() {
for (let index = 1; index < length; index++) {
const fileName = `segment${index}_1_av.ts`
console.log(`file '${fileName}'`)
}
}
getFileList();
Agora, copiamos o resultado para um ficheiro de nome segmentlist.txt
.
Corremos finalmente o comando do FFmpeg com o concat
e o nosso vĂdeo estará pronto com o nome all.ts
, visto que, neste caso, a extensĂŁo dos fragmentos era TS.