Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Olá pessoal.
Estava vendo sites como o vagalume.com.br, letras.terra.com.br ou até mesmo o letras.com.br e eles tem um sistema de legendas muito interessante.
Gostaria de saber como funciona esse sistema, creio eu q seja em javascript. eu sei php muito bem mais não sou tão bom em javascript. por onde eu poderia começar para criar um sistema como este, ou mais básico.
Obrigado e qualquer ajuda é bem vinda.
Não pow os videos do youtube não tem legenda, esse é um esquema do proprio site.
Pelo que eu vi, provavelmente eles possuem um array com os tempos entre cada frase, e então lendo a letra da música, conseguem fazer a sincronia.
Demorou um pouco, mas acho que descobri como funciona.
As legendas vêm de de uma URL nesse formato:
http://letras.terra.com.br/legenda.php?id_video=XXX&id_musica=YYY
Onde:
-
XXX
Refere-se ao ID do vídeo que é o identificado do YouTube do vídeo associado à música sendo visualizada
-
YYY
Refere-se ID da Música que pode ser obtido a partir do próprio URL da página visualizada
Testei com a primeira música que vi no Letras do Terra, uma musiquinha feita chamada Wish You Were Here da Avril Lavigne.
A URL ficou assim:
http://letras.terra.com.br/legenda.php?id_video=VT1-sitWRtY&id_musica=1837752
Seja lá qual for a linguagem que vá fazer, se estritamente com JavaScript ou se via servidor, você vai ter de abrir esse URL e manipular o texto retornado.
Com PHP, que foi como fiz (bem mais rápido pra mim), ficou:
<?php
$legenda = file_get_contents( 'http://letras.terra.com.br/legenda.php?id_video=VT1-sitWRtY&id_musica=1837752' );
print '<pre>'; print_r( json_decode( $legenda ) );
E obtive como saída (em SPOILER, pois é meio grande e não quero quebrar o layout do fórum):
stdClass Object
(
[o] => stdClass Object
(
[id_legenda] => 1502
[id_musica] => 1837752
[id_traducao] =>
[id_video] => VT1-sitWRtY
[legenda] => [["I can be tough","5.5","7.2"],["I can be strong","8.2","10.0"],["But with you It's not like that at all","11.4","16.3"],["There's a girl","17.1","18.8"],["That gives a shit","20.0","21.6"],["Behind this wall","22.8","24.4"],["You just walk through it","25.4","27.7"],["And I remember","28.3","29.6"],["All those crazy things you said","29.8","31.8"],["You left them running through my head","32.0","34.8"],["You're always there","35.0","36.3"],["You're everywhere","36.5","37.6"],["But right now I wish you were here","37.9","40.5"],["All those crazy things we did","41.1","43.5"],["Didn't think about it","43.8","45.4"],["Just went with it","45.5","46.6"],["You're always there","46.9","48.0"],["You're everywhere","48.2","49.1"],["But right now I wish you were here","49.6","52.2"],["Damn, Damn, Damn","52.4","55.6"],["What I'd do to have you","56.0","58.7"],["Here, here, here","58.7","61.5"],["I wish you were here","62.1","63.9"],["Damn, Damn, Damn","64.2","67.2"],["What I'd do to have you","67.6","69.6"],["Near, near, near","69.7","72.9"],["I wish you were here","73.3","75.7"],["I love the way you are","75.8","79.9"],["It's who I am","80.5","82.1"],["Don't have to try hard","83.5","85.5"],["We always say","86.5","88.5"],["Say it like it is","89.0","90.8"],["And the truth","92.0","93.5"],["Is that a really miss","94.8","97.8"],["All those crazy things you said","99.0","101.4"],["You left them running through my head","101.9","104.5"],["You're always there","104.7","105.7"],["You're everywhere","105.9","107.1"],["But right now I wish you were here","107.4","110.0"],["All those crazy things we did","110.4","112.8"],["Didn't think about","113.1","114.2"],["Just went with it","114.4","115.8"],["You're always there","116.1","117.5"],["You're everywhere","117.6","118.9"],["But right now I wish you were here","119.1","121.7"],["Damn, Damn, Damn","121.9","125.1"],["What I'd do to have you","125.6","127.5"],["Here, here, here","127.7","130.8"],["I wish you were here","131.2","133.2"],["Damn, Damn, Damn","133.5","136.6"],["What I'd do to have you","136.9","139.0"],["Near, near, near","139.2","142.5"],["I wish you were here","142.7","145.1"],["No I don't wanna let go","146.0","147.9"],["I just wanna let you know","149.2","150.8"],["That I never want to let go, oh, oh","151.7","157.0"],["No I don't wanna let go","157.6","159.9"],["I just wanna let you know","160.7","162.7"],["That I never want to let go, let go, let go,let go,let go,let go,let go!!","163.2","172.0"],["Damn, Damn, Damn","174.3","177.1"],["What I'd do to have you","177.6","179.4"],["Here, here, here","179.6","182.8"],["I wish you were here","183.3","185.2"],["Damn, Damn, Damn","185.7","188.6"],["What I'd do to have you","189.4","191.3"],["Near, near, near","191.5","194.7"],["I wish you were here","194.9","197.1"],["Damn, Damn, Damn","197.1","200.4"],["What I'd do to have you","200.7","202.7"],["Here, here, here","202.9","206.1"],["I wish you were here","206.5","208.5"],["Damn, Damn, Damn","208.8","211.9"],["What I'd do to have you","212.3","214.2"],["Near, near, near","214.5","217.5"],["I wish you were here","218.0","220.3"]]
[id_usuario] => 540721
)
[t] => stdClass Object
(
[id_legenda] => 2070
[id_musica] => 1837752
[id_traducao] => 160572
[id_video] => VT1-sitWRtY
[legenda] => [["Eu gostaria que voc\u00ea estivesse aqui","0.2","0.3"],["Eu posso ser dura","5.2","7.2"],["Eu posso ser forte","8.1","9.9"],["Mas com voc\u00ea, isso n\u00e3o \u00e9 assim mesmo?","11.2","15.8"],["H\u00e1 uma menina","17.1","19.2"],["Que d\u00e1 a minima","19.9","21.7"],["Atr\u00e1s dessa parede","22.4","24.5"],["Voc\u00ea simplesmente caminha","25.4","27.8"],["E eu me lembro","28.3","29.2"],["De todas as coisas loucas que voc\u00ea disse","29.2","31.8"],["Voc\u00ea as deixou correrem pela minha cabe\u00e7a","31.9","34.3"],["Voc\u00ea est\u00e1 sempre l\u00e1","35.0","36.3"],["Voc\u00ea est\u00e1 em todo lugar","36.6","37.6"],["Mas agora mesmo, eu gostaria que voc\u00ea estivesse aqui","37.9","40.4"],["Todas as coisas loucas que fizemos","40.8","43.3"],["N\u00e3o pensamos sobre elas","43.7","45.2"],["S\u00f3 fomos com elas","45.2","46.5"],["Voc\u00ea est\u00e1 sempre l\u00e1","46.6","47.9"],["Voc\u00ea est\u00e1 em todo lugar","47.9","49.4"],["Mas agora mesmo, eu gostaria que voc\u00ea estivesse aqui","49.5","51.8"],["Droga, Droga, Droga","52.3","55.2"],["O que eu faria para ter voc\u00ea","55.9","58.2"],["Aqui, aqui, aqui","58.4","61.2"],["Eu gostaria que voc\u00ea estivesse aqui","62.2","63.6"],["Droga, Droga, Droga","63.8","67.2"],["O que eu faria para ter voc\u00ea","67.2","69.7"],["Perto, perto, perto","69.8","72.6"],["Eu gostaria que voc\u00ea estivesse aqui","72.7","75.3"],["Eu amo seu jeito","75.5","79.4"],["\u00c9 quem eu sou","80.3","82.2"],["N\u00e3o tem que tentar mais","83.2","85.6"],["N\u00f3s sempre dizemos","86.3","88.5"],["\"Somos t\u00e3o sortudos\"","89.3","91.0"],["E a verdade","91.9","93.9"],["\u00c9 essa, realmente errada","94.6","97.3"],["De todas as coisas loucas que voc\u00ea disse","99.0","101.2"],["Voc\u00ea as deixou correrem pela minha cabe\u00e7a","101.6","104.0"],["Voc\u00ea est\u00e1 sempre l\u00e1","104.4","105.6"],["Voc\u00ea est\u00e1 em todo lugar","105.8","107.2"],["Mas agora mesmo, eu gostaria que voc\u00ea estivesse aqui","107.3","109.5"],["De todas as coisas loucas que fizemos","110.2","112.6"],["N\u00e3o pensamos sobre elas","113.2","114.3"],["S\u00f3 fomos com elas","114.7","115.8"],["Voc\u00ea est\u00e1 sempre l\u00e1","116.0","117.3"],["Voc\u00ea est\u00e1 em todo lugar","117.5","118.6"],["Mas agora mesmo, eu gostaria que voc\u00ea estivesse aqui","118.9","121.3"],["Droga, Droga, Droga","122.1","124.7"],["O que eu faria para ter voc\u00ea","125.1","127.6"],["Aqui, aqui, aqui","127.9","130.6"],["Eu gostaria que voc\u00ea estivesse aqui","130.9","133.2"],["Droga, Droga, Droga","133.4","136.6"],["O que eu faria para ter voc\u00ea","137.0","139.1"],["Perto, perto, perto","139.4","142.4"],["Eu gostaria que voc\u00ea estivesse aqui","142.6","144.6"],["N\u00e3o eu, Eu n\u00e3o quero deixar ir","146.3","148.0"],["S\u00f3 quero que voc\u00ea saiba","148.4","150.8"],["Que eu nunca deixarei ir, deixarei ir oh oh","151.6","156.5"],["N\u00e3o eu, Eu n\u00e3o quero deixar ir","156.6","159.8"],["S\u00f3 quero que voc\u00ea saiba","159.9","162.7"],["Que eu nunca deixarei ir, deixarei ir, deixarei ir, deixarei ir, deixarei ir!!","163.1","173.4"],["Droga, Droga, Droga","174.1","177.0"],["O que eu faria para ter voc\u00ea","177.6","179.2"],["Aqui, aqui, aqui","179.2","182.8"],["Eu gostaria que voc\u00ea estivesse aqui","183.1","185.2"],["Droga, Droga, Droga","185.4","189.0"],["O que eu faria para ter voc\u00ea","189.1","191.1"],["Perto, perto, perto","191.3","194.4"],["Eu gostaria que voc\u00ea estivesse aqui","194.7","196.9"],["Droga, Droga, Droga","196.9","200.0"],["O que eu faria para ter voc\u00ea","200.2","202.6"],["Aqui, aqui, aqui","202.7","206.1"],["Eu gostaria que voc\u00ea estivesse aqui","206.4","208.2"],["Droga, Droga, Droga","208.6","211.9"],["O que eu faria para ter voc\u00ea","212.0","214.6"],["Perto, perto, perto","214.6","217.7"],["Eu gostaria que voc\u00ea estivesse aqui","217.9","221.2"]]
[id_usuario] => 2071533
)
[lastModified] => Fri, 16 Sep 2011 10:57:12
)
Como pode ver existem duas entradas: o, da legenda original e t, da traduzida e uma terceira com a última vez que a legenda foi modificada.
O que interessa para exibição realmente é o índice legenda de qualquer um dos dois primeiros citados.
Porém, pode ser que haja retorno com apenas um índice, apenas a original ou apenas a traduzida dependendo do vídeo.
Assim como pode não ter nenhum, caso a música seja extremamente nova.
O script completo que o site usa, seria esse e eu acredito que parte referente às legendas, essa:
var b = this,
c = $("#pl_leg", a);
arrSubtitles = {};
lastPosition = 0;
hasTradLeg = hasOrigLeg = !1;
jsonLeg = {};
tmpJsonLeg = {};
this.idCorr = this.idContrib = this.switchVideo = this.toFull = !1;
// ...
this.getSubtitles = function (c) {
var e = "/legenda.php?id_video=" + c + "&id_musica=" + SS.letras.artista.getOpcoes("id_musica");
b.idContrib ? e = "/legenda.php?id_contrib=" + b.idContrib + "&id_video=" + c : b.idCorr && (e = "/legenda.php?id_correcao=" + b.idCorr + "&id_video=" + c);
$.ajax({
url: e,
type: "GET",
cache: !0,
dataType: "json",
async: !0,
success: function (e) {
if (e) {
g.hasSubtitles = !0;
$("#pl_leg_sincvid, #pl_lenv_leg", a).remove();
$("#ico_leg a b").html("Legenda");
if (e.t && !e.o) hasTradLeg = !0, hasOrigLeg = !1, tmpJsonLeg = {}, jsonLeg = e.t, jsonLeg.legenda = $.parseJSON(jsonLeg.legenda);
else if (!e.t && e.o) hasTradLeg = !1, hasOrigLeg = !0, tmpJsonLeg = {}, jsonLeg = e.o, jsonLeg.legenda = $.parseJSON(jsonLeg.legenda);
else if (e.t && e.o) hasOrigLeg = hasTradLeg = !0, jsonLeg = e.o, jsonLeg.legenda = $.parseJSON(jsonLeg.legenda), tmpJsonLeg = e.t, tmpJsonLeg.legenda = $.parseJSON(tmpJsonLeg.legenda);
b.bindEvents();
SS.util.cache.get("pcloseLegenda") == "undefined" || !SS.util.cache.get("pcloseLegenda") ? (a.addClass("pl_leg"), b.btnLeg.hide()) : b.closeSubtitle()
} else b.closeLeg(c);
pa();
h.estado == 4 && J()
}
})
};
this.closeLeg = function (c) {
g.hasSubtitles = b.idContrib = b.idCorr = !1;
$("#pl_v", a).append(b.btnSendLeg(c));
$("#pl_leg_sincvid", a).remove();
jsonLeg = tmpJsonLeg = {};
lastPosition = 0;
a.removeClass("pl_leg");
b.btnLeg.hide()
};
this.readSubtitle = function (a) {
if (a == 0 || jsonLeg.legenda.length == 0) return !1;
for (var b = lastPosition, d = !1, k = lastPosition; k < jsonLeg.legenda.length; k++) if (!(a > jsonLeg.legenda[jsonLeg.legenda.length - 1][2]) && a > jsonLeg.legenda[k][1] && a < jsonLeg.legenda[k][2]) {
d = !0;
if (k !== 0 && b == k) break;
lastPosition = k;
c.html(jsonLeg.legenda[k][0]);
break
}
d || c.html("")
};
A parte que parece interessar, seria esse último método.
De acordo com a estrutura do índice legenda, o primeiro índice é o texto e os outros dois os tempos inicial e final, ou quando elas (as frases) aparecem e somem.
Com todas essas informações, achpo que já dá pra fazer alguma coisa.
Mas aí já é uma coisa que meu conhecimento limitado em JavaScript não pode mais ajudar. :(
Que sistema de legendas? Nos vídeos?
Se for me parece ser coisa do próprio YouTube.