Introdução
Na referência [1] eu mostrei como é possível obter as legendas de vídeos do youtube de forma manual. Ficou faltando um script como uma prova de conceito, porém, hoje, postarei um script em python que baixa legendas de vídeos do youtube.
O código
Primeiro o código:
#!/usr/bin/env python # -*- coding: utf-8 -*- # # [XML2SRT.py] # Módulo que realiza o download e conversão de legendas # do youtube. # # [Autor] # Marcos Paulo Ferreira (Daemonio) # undefinido at gmail com # https://daemoniolabs.wordpress.com # # Versão 1.0 by daemonio @ Thu Aug 1 20:00:06 BRT 2013 # import urllib2 from xml.dom import minidom import xml.parsers.expat import HTMLParser class URLNotFound(Exception): pass class XMLError(Exception): pass class XML2SRT(): def __init__(self, idvideo): self.idvideo = idvideo def getList(self): """ Obtém a lista de legendas disponíveis """ url = 'http://video.google.com/timedtext?type=list&v='+self.idvideo # Carrega a URL try: source = urllib2.urlopen(url).read() except urllib2.HTTPError: raise URLNotFound('Cant load URL: '+url) # Carrega o XML try: xmlDoc = minidom.parseString(source) except xml.parsers.expat.ExpatError: raise XMLError('Cant parser XML file.') # Monta a lista sublist=[] for x in xmlDoc.getElementsByTagName('track'): lang_t=x.getAttribute('lang_translated') name=x.getAttribute('name') lang_code=x.getAttribute('lang_code') sublist.append([lang_t, name, lang_code]) return sublist def tempo_subrip(self, xtime): """ Converte um tempo em segundos no formato de tempo SubRip """ subtime=[] timetxt='' if '.' not in xtime: xtime+='.000' SEC,MILI=xtime.split('.') SEC=int(SEC) while len(MILI) < 3: MILI=MILI+'0' subtime.append(str(SEC/3600)) subtime.append(str((SEC%3600)/60)) subtime.append(str((SEC%3600)%60)) for i in range(3): if 1 == len(subtime[i]): subtime[i]='0'+subtime[i] i=':'.join(subtime)+','+MILI return i.encode('utf-8') def getSub(self, lang_code, name): """ Retorna a legenda indicada pelos parâmetros lang_code e name. A legenda é retornada de forma completa como uma string. """ name=urllib2.quote(name) url = 'http://video.google.com/timedtext?type=track&v='+self.idvideo url = url + '&lang='+lang_code+'&name='+name try: source = urllib2.urlopen(url).read() except urllib2.HTTPError: raise URLNotFound('Cant load URL: '+url) try: xmlDoc = minidom.parseString(source) except xml.parsers.expat.ExpatError: raise XMLError('Cant parser XML file.') captionsList = xmlDoc.getElementsByTagName('text') ; srtext='' for id, x in enumerate(captionsList, 1): try: caption = x.firstChild.data except AttributeError: continue # Atributos de tempos. Algumas legendas nao tem 'dur' # e isso gera a exceção ValueError. start=float(x.getAttribute('start')) try: dur=float(x.getAttribute('dur')) except ValueError: dur=0 end=start+dur srtext += str(id) + '\n' srtext += self.tempo_subrip(str(start)) + ' --> ' + self.tempo_subrip(str(end)) + '\n' srtext += HTMLParser.HTMLParser().unescape(caption).encode('utf-8') + '\n' srtext += '\n' return srtext[:-1] if __name__ == '__main__': import sys argc = len(sys.argv) if argc < 3: print '[uso]',sys.argv[0],'<codigo video> <arquivo saida>' sys.exit(-1) # Lê os parâmetros idvideo = sys.argv[1] outputfile = sys.argv[2] # Cria a instância subobj = XML2SRT(idvideo) try: # Lista de legendas sublist = subobj.getList() except URLNotFound: print 'Erro: Código inválido.' sys.exit(-1) except XMLError: print 'Erro: Vídeo sem legenda.' sys.exit(-1) # Monta um menu de escolha print 'Selecione o idioma (-1 = sair)' l = len(sublist) for c, [label, name, idlang] in enumerate(sublist): print '[',c,']',label # Lê a opção opt=int(raw_input('>> ')) # Recupera os atributos da opção digitada # e escreve a legenda no arquivo passado. if opt >= 0 and opt < len(sublist): try: filefd=open(outputfile, 'w') except: print 'Erro: Impossível criar arquivo.' sys.exit(-1) else: label, name, idlang = sublist[opt] filefd.write(subobj.getSub(idlang, name)) finally: filefd.close()
salve como XML2SRT.py
Exemplos
Baixado o script, transforme-o em executável:
$ chmod +x XML2SRT.py
Em seguida, execute-o:
$ ./XML2SRT.py [uso] ./XML2SRT.py <codigo video> <arquivo saida>
Devemos passar o código do vídeo no primeiro parâmetro e o arquivo de saída (que conterá a legenda) no segundo. Utilizarei o vídeo exemplo de [1] para teste:
$ ./XML2SRT.py kGYACultjCY legenda_portugues.srt Selecione o idioma (-1 = sair) [ 0 ] Czech [ 1 ] Dutch [ 2 ] English [ 3 ] French [ 4 ] German [ 5 ] Hebrew [ 6 ] Italian [ 7 ] Japanese [ 8 ] Polish [ 9 ] Portuguese [ 10 ] Spanish [ 11 ] Swedish >> 9
O script apresenta em forma de menu todas as legendas disponíveis para o vídeo e, com isso, basta selecionar o número do idioma desejado e apertar enter. No exemplo acima, a legenda em português foi gravada no arquivo legenda_portugues.srt:
$ head -n 15 legenda_portugues.srt 1 00:00:00,880 --> 00:00:02,680 RIDLEY SCOTT EM A VIDA EM UM DIA 2 00:00:03,080 --> 00:00:06,680 Deveria ser pessoal. Deve ser pessoal. É isso que estamos procurando. 3 00:00:07,160 --> 00:00:12,000 Na verdade, o que importa é o que agrada você como autor. 4 00:00:12,680 --> 00:00:14,160 O primeiro filme que eu fiz foi um dia na minha vida.
Agora só baixar o vídeo e usar a legenda :-D
Conclusão
Esse é um dos meus primeiros scripts em Python e por isso, se encontrarem algum erro ou até mesmo dica de implementação, podem falar comigo. Ah, existem outros scripts com o nome XML2SRT, porém decidi deixar assim mesmo porque todos eles, ao meu ver, são scripts pessoais e pouco divulgados. Acredito que não tenha problema algum :-o
Referências
[1] Download e Conversão de Legendas Do Youtube by Daemonio (Acessado em: Agosto/2013)
https://daemoniolabs.wordpress.com/2012/11/21/download-e-conversao-de-legendas-do-youtube/