{Youtube} – Effectuer des recherches dans les dialogues d’une vidéo
Salut à tous,
Aujourd'hui je suis vraiment très très près de l'heure de ma soutenance ... ce qui explique un peu le manque de frénésie que j'ai dans la publication de mes articles ;)
10 ans se sont passé depuis la dernière fois que j'ai obtenu un diplôme, autant dire que la pression est à son comble !
Cela dit, j'étais l'autre jour sur une vidéo avec un titre un peu ... "putaclick" (ou accrocheur comme diraient certains utilisateurs de spip ;) )
Et j'avais très envie de me rendre à l'instant qui traitait du sujet évoqué dans ce titre ... sauf que j'ai dû me faire toute la vidéo d'une vingtaine de minutes ... pour trouver ce que je cherchais ( qui ne valait pas grand chose d'ailleurs)
Alors je me suis dit que ça serait sympa de développer un petit outil pour faire le job de rechercher dans les dialogues d'une vidéo.
Bien entendu, certaines personnes l'ont déjà fait, et je ne vous cacherais pas qu'il existe déjà des extensions qui le proposent.
Mais moi, je vous propose de vous expliquer techniquement comment j'ai fait ;)
Utilisation des sous-titres dans Youtube
Ouvrez vos consoles (touche F12 de votre clavier), et allez sur Youtube.
Sélectionnez une vidéo de votre choix, en vous assurant que celle-ci dispose de sous-titre (automatique ou non)
Vous êtes donc fin prêt !
Vous devriez avoir un onglet "réseau" dans la console, c'est le moment de l'ouvrir et de voir ce qu'il s'y passe lorsque vous activez ou désactivez les sous-titres.
Super, vous avez trouvé la requête que Youtube effectue pour télécharger les sous-titres d'une vidéo.
L'url de cette requête est accessible depuis : window.ytInitialPlayerResponse.captions.playerCaptionsRenderer.baseUrl
Variable que vous pourrez retrouver en regardant le code source de la page Youtube que vous consultez en faisant une simple recherche du terme timedText.
Cependant cette URL ne vous sera pas d'un très grand secours car pour la générer il y a tout un tas de valeurs qui sont envoyées dans l'entête de cette requête ( Youtube se protège ;) )
Réécriture d'une fonction utilisée pour faire des requêtes
Souvent lorsque vous utilisez du JQuery (ou autres lib / framework) et que vous faite du $.get, $.post .... etc ... le vrai objet natif de Javascript qui est utilisé c'est "XMLHttpRequest", il dispose de tout un arsenal de fonctions permettant de faire de belles requêtes
.
J'ai donc pris la liberté de le modifier pour me renvoyer le résultat de toutes les requêtes faites par Youtube.
Dès que je reconnais des sous-titres c'est bueno !
Le Javascript ci-dessus modifie la méthode "send" de l'objet XMLHttpRequest, ainsi dès qu'une requête est envoyée, je reçois immédiatement le retour de celle-ci, je le parse, et je vérifie la présence d'une balise "<timedtext>" !
J'obtiens donc assez facilement les sous-titres
Chaque phrase est contenue dans une balise <p>, et chaque mot dans une balise <s>.
Chaque phrase dispose dans sa balise <p> d'un attribut "t=", il s'agit en millisecondes du moment où celui-ci est utilisé dans la vidéo, vous avez également un attribut "t=" sur les mots <s>, celui-ci est un temps "additionnel", lorsque les sous-titres sont affichés mot à mot et non pas phrase par phrase.
Le script
Je vous ai donc comme à mon habitude concocté un super script qui vous permettra via une jolie barre de recherche, d'effectuer dans les sous-titres d'une vidéo (en fonction de la langue choisie) la recherche de votre choix. Il vous suffira de cliquer sur un mot pour que la vidéo se positionne automatiquement à l'endroit où celui-ci est utilisé.
Vidéo de démonstration
Petite vidéo de comment utiliser mon script.
Bon visionnage, pensez à vous abonner à la chaîne et / ou laisser un petit j'aime / commentaire d'encouragement. Merci à tous
Les idées d'évolution possible
Cet article n'apporte rien de spécialement extraordinaire, cependant avec l’avènement du html5, il est parfaitement possible d'extraire des images d'une vidéo, il serait donc assez rigolo de coupler des images de la vidéos avec la technologie tensorflow (qui permet de faire de la reconnaissance) pour faire des recherches d'objets ou d'élément d'une vidéo ! Libre à l'imagination des développeurs :)
Conclusion
Les vacances arrivent, de mon côté j'ai déposé ma démission car je quitte le monde des SSII / ESN pour travailler chez un éditeur ... avec une période d'essaie de 8 mois (outch), le tout couplé à un futur déménagement, l'année s'annonce corsée ^^
Je crois que le plus moche c'est surtout de n'avoir pas l'autorisation de communiquer directement à mon client mon projet de départ ...
Cela dit, peut-être lira-t-il mon blog :D
Merci à tous pour vos commentaires et encouragements, bon weekend à tous !
Encore une fois merci pour ce super article !
Et surtout bonne suite pour tous ces changements :-)
Le script ne marche pas sur ma machine, j’ai du remplacer la ligne
[pastacode lang="javascript" manual="document.getElementsByTagName('video')%5B0%5D.currentTime%20%3D%20parseInt(e.target.parentNode.getAttribute('t'))%2F1000%3B" message="" highlight="" provider="manual"/]
par
[pastacode lang="javascript" manual="document.getElementsByTagName('video')%5B0%5D.currentTime%20%3D%20parseInt(e.target.outerHTML.match(%2F.*t%3D%22(%5Cd%2B).*%22%2F)%5B1%5D)%2F1000%3B" message="" highlight="" provider="manual"/]
Petit ajustement:
[pastacode lang="javascript" manual="document.getElementsByTagName('video')%5B0%5D.currentTime%20%3D%20parseInt(e.target.parentNode.getAttribute('t')%20%7C%7C%20e.target.outerHTML.match(%2F.*%3Ft%3D%22(%5Cd%2B).*%22%2F)%5B1%5D)%2F1000%3B" message="" highlight="" provider="manual"/]
Et pour une recherche insensible à la casse
remplacer :
res[i].textContent.indexOf(evt.target.value)!= -1
par :
res[i].textContent.match(new RegExp(evt.target.value, ‘gi’)) != null