mirror of
https://github.com/LaQuay/TDTChannels.git
synced 2024-11-26 10:49:13 +01:00
commit
43215bfc00
3 changed files with 221 additions and 185 deletions
|
@ -17,78 +17,82 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container" style="margin-top: 30px; margin-bottom: 30px; padding-bottom: 50px;">
|
<div class="container" style="margin-top: 30px">
|
||||||
<h1 class="display-3">TDTChannels</h1>
|
<h1 class="display-4">TDTChannels</h1>
|
||||||
<p class="lead">
|
|
||||||
Bienvenido al reproductor del proyecto opensource TDTChannels
|
|
||||||
</p>
|
|
||||||
<br>
|
<br>
|
||||||
<a class="btn btn-outline-secondary" role="button" href="https://github.com/LaQuay/TDTChannels"
|
<a class="btn btn-outline-secondary" role="button" href="https://github.com/LaQuay/TDTChannels"
|
||||||
target="_blank">Repositorio TDT Channels</a>
|
target="_blank">Repositorio TDT Channels</a>
|
||||||
<a class="btn btn-outline-success" role="button" href="http://www.marcvila.me/"
|
<a class="btn btn-outline-success" role="button" href="http://www.marcvila.me/"
|
||||||
target="_blank">Sitio personal</a>
|
target="_blank">Marc Vila</a>
|
||||||
<a class="btn btn-outline-warning" role="button" href="https://github.com/LaQuay/"
|
<a class="btn btn-outline-warning" role="button" href="https://github.com/LaQuay/"
|
||||||
target="_blank">GitHub</a>
|
target="_blank">GitHub</a>
|
||||||
<a class="btn btn-outline-primary" role="button" href="https://www.linkedin.com/in/marcvilagomez/"
|
<a class="btn btn-outline-primary" role="button" href="https://www.linkedin.com/in/marcvilagomez/"
|
||||||
target="_blank">LinkedIn</a>
|
target="_blank">LinkedIn</a>
|
||||||
<div style="margin-top: 25px">
|
<div class="row" style="margin-top: 40px;">
|
||||||
<div id="video">
|
<div class="col-xs-4 col-md-4">
|
||||||
<p class="lead">
|
<div class="list-group channels-list"></div>
|
||||||
Reproductor de Televisión
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<input id="input-reproduccion-video" type="text" class="form-control" placeholder="URL de reproducción">
|
|
||||||
<div class="input-group-append">
|
|
||||||
<button class="btn btn-outline-secondary" type="button" id="button-reproduccion-video"
|
|
||||||
onclick="loadItem('video');">Cargar
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div id="video-player"></div>
|
|
||||||
<div id="video-information" class="shadow-sm p-3 mb-5 bg-white rounded" style="margin-top: 15px">
|
|
||||||
<p class="lead">Información de la reproducción</p>
|
|
||||||
Formatos soportados
|
|
||||||
<br>
|
|
||||||
<em>m3u8</em>
|
|
||||||
<br><br>
|
|
||||||
Resoluciones disponibles
|
|
||||||
<br>
|
|
||||||
<em id="video-resolution"></em>
|
|
||||||
<p id="extra-video-info" style="display: block"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="audio" style="margin-top: 15px">
|
<div class="col-xs-8 col-md-8">
|
||||||
<p class="lead">
|
<div id="video">
|
||||||
Reproductor de Radio
|
<p class="lead">
|
||||||
</p>
|
Reproductor de Televisión
|
||||||
<div class="input-group mb-3">
|
</p>
|
||||||
<input id="input-reproduccion-audio" type="text" class="form-control" placeholder="URL de reproducción">
|
|
||||||
<div class="input-group-append">
|
<div class="input-group mb-3">
|
||||||
<button class="btn btn-outline-secondary" type="button" id="button-reproduccion-audio"
|
<input id="input-reproduccion-video" type="text" class="form-control"
|
||||||
onclick="loadItem('audio');">Cargar
|
placeholder="URL de reproducción">
|
||||||
</button>
|
<div class="input-group-append">
|
||||||
|
<button class="btn btn-outline-secondary" type="button" id="button-reproduccion-video"
|
||||||
|
onclick="loadItem('video');">Cargar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="video-player"></div>
|
||||||
|
<div id="video-information" class="shadow-sm p-3 mb-5 bg-white rounded" style="margin-top: 15px">
|
||||||
|
<p class="lead">Información de la reproducción</p>
|
||||||
|
Formatos soportados
|
||||||
|
<br>
|
||||||
|
<em>m3u8</em>
|
||||||
|
<br><br>
|
||||||
|
Resoluciones disponibles
|
||||||
|
<br>
|
||||||
|
<em id="video-resolution"></em>
|
||||||
|
<p id="extra-video-info" style="display: block"></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<audio id="audio-controller" controls autoplay="">
|
<div id="audio" style="margin-top: 15px">
|
||||||
<source id="audio-player" src="" type="audio/mpeg">
|
<p class="lead">
|
||||||
Your browser does not support the audio element.
|
Reproductor de Radio
|
||||||
</audio>
|
</p>
|
||||||
<div id="audio-information" class="shadow-sm p-3 mb-5 bg-white rounded" style="margin-top: 15px">
|
<div class="input-group mb-3">
|
||||||
<p class="lead">Información de la reproducción</p>
|
<input id="input-reproduccion-audio" type="text" class="form-control"
|
||||||
Formatos soportados
|
placeholder="URL de reproducción">
|
||||||
<br>
|
<div class="input-group-append">
|
||||||
<em>aac</em>, <em>mp3</em>, <em>nsv</em>, <em>audio/mpeg</em>, <em>pls</em>(Beta)
|
<button class="btn btn-outline-secondary" type="button" id="button-reproduccion-audio"
|
||||||
|
onclick="loadItem('audio');">Cargar
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<audio id="audio-controller" controls autoplay="">
|
||||||
|
<source id="audio-player" src="" type="audio/mpeg">
|
||||||
|
Your browser does not support the audio element.
|
||||||
|
</audio>
|
||||||
|
<div id="audio-information" class="shadow-sm p-3 mb-5 bg-white rounded" style="margin-top: 15px">
|
||||||
|
<p class="lead">Información de la reproducción</p>
|
||||||
|
Formatos soportados
|
||||||
|
<br>
|
||||||
|
<em>aac</em>, <em>mp3</em>, <em>nsv</em>, <em>audio/mpeg</em>, <em>pls</em>(Beta)
|
||||||
|
|
||||||
<div id="extra-audio-info-div" style="display: none; padding-top: 20px">
|
<div id="extra-audio-info-div" style="display: none; padding-top: 20px">
|
||||||
<button class="btn btn-secondary" type="button" data-toggle="collapse"
|
<button class="btn btn-secondary" type="button" data-toggle="collapse"
|
||||||
data-target="#collapseAlternativas"
|
data-target="#collapseAlternativas"
|
||||||
aria-expanded="false" aria-controls="collapseAlternativas">
|
aria-expanded="false" aria-controls="collapseAlternativas">
|
||||||
URLs alternativas
|
URLs alternativas
|
||||||
</button>
|
</button>
|
||||||
<div class="collapse" id="collapseAlternativas">
|
<div class="collapse" id="collapseAlternativas">
|
||||||
<div class="card card-body">
|
<div class="card card-body">
|
||||||
<p id="extra-audio-info"></p>
|
<p id="extra-audio-info"></p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -108,132 +112,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
// Se espera en la URL este tipo de llamada
|
var player;
|
||||||
// .html?type={audio,video}&channel={url_a_reproducir}
|
|
||||||
var player;
|
|
||||||
|
|
||||||
var typeToReproduce = getUrlParameter("type");
|
var typeToReproduce = getUrlParameter("type");
|
||||||
var channelToReproduce;
|
var channelToReproduce;
|
||||||
if (typeToReproduce == "audio") {
|
if (typeToReproduce == "audio") {
|
||||||
channelToReproduce = getUrlParameter("channel");
|
channelToReproduce = getUrlParameter("channel");
|
||||||
reproduceAudio(channelToReproduce);
|
reproduceAudio(channelToReproduce);
|
||||||
} else if (typeToReproduce == "video") {
|
} else if (typeToReproduce == "video") {
|
||||||
channelToReproduce = getUrlParameter("channel");
|
channelToReproduce = getUrlParameter("channel");
|
||||||
reproduceVideo(channelToReproduce);
|
reproduceVideo(channelToReproduce);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadItem(from) {
|
|
||||||
var value;
|
|
||||||
if (from == "audio") {
|
|
||||||
value = document.getElementById("input-reproduccion-audio").value;
|
|
||||||
reproduceAudio(value);
|
|
||||||
} else if (from == "video") {
|
|
||||||
value = document.getElementById("input-reproduccion-video").value;
|
|
||||||
reproduceVideo(value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function reproduceVideo(channelToReproduce) {
|
|
||||||
console.log("Reproducing video: " + channelToReproduce);
|
|
||||||
if (channelToReproduce.includes("m3u8")) {
|
|
||||||
var divInfo = document.getElementById("video-player").childElementCount;
|
|
||||||
if (divInfo == 0) {
|
|
||||||
player = new Clappr.Player({
|
|
||||||
source: channelToReproduce,
|
|
||||||
parentId: '#video-player',
|
|
||||||
height: '500px',
|
|
||||||
width: '100%',
|
|
||||||
autoPlay: true,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
// Assume player instance is already created
|
|
||||||
player.configure({
|
|
||||||
source: channelToReproduce,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
clearResolutions();
|
|
||||||
getResolution(channelToReproduce, updateResolution);
|
|
||||||
}
|
|
||||||
|
|
||||||
ga('send', {
|
|
||||||
hitType: 'event',
|
|
||||||
eventCategory: 'Video',
|
|
||||||
eventAction: 'play',
|
|
||||||
eventLabel: channelToReproduce
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function reproduceAudio(channelToReproduce) {
|
|
||||||
if (channelToReproduce.includes("pls")) {
|
|
||||||
getURLsFromPLS(channelToReproduce, reproducePLSFromUrl);
|
|
||||||
} else {
|
|
||||||
reproduceAudioFromUrl(channelToReproduce);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function reproduceAudioFromUrl(channelToReproduce) {
|
|
||||||
console.log("Reproducing audio: " + channelToReproduce);
|
|
||||||
var audioSource = document.getElementById('audio-controller');
|
|
||||||
var audioPlayer = document.getElementById('audio-player');
|
|
||||||
|
|
||||||
audioPlayer.src = channelToReproduce;
|
|
||||||
audioSource.load();
|
|
||||||
audioSource.pause();
|
|
||||||
|
|
||||||
var playPromise = audioSource.play();
|
|
||||||
if (playPromise !== undefined) {
|
|
||||||
playPromise.then(function() {
|
|
||||||
// Automatic playback started!
|
|
||||||
}).catch(function(error) {
|
|
||||||
// Automatic playback failed.
|
|
||||||
// Show a UI element to let the user manually start playback.
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
ga('send', {
|
|
||||||
hitType: 'event',
|
|
||||||
eventCategory: 'Audio',
|
|
||||||
eventAction: 'play',
|
|
||||||
eventLabel: channelToReproduce
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function reproducePLSFromUrl(data) {
|
|
||||||
reproduceAudioFromUrl(data[0]);
|
|
||||||
updateExtraAudioInfo("pls_more_url_available", data);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateResolution(resolutions) {
|
|
||||||
console.log("Resoluciones: " + resolutions);
|
|
||||||
|
|
||||||
for (i = 0; i < resolutions.length; i++) {
|
|
||||||
var resolutionToAdd = resolutions[i];
|
|
||||||
if (i < resolutions.length - 1){
|
|
||||||
resolutionToAdd += ", ";
|
|
||||||
}
|
|
||||||
document.getElementById("video-resolution").innerHTML += resolutionToAdd;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function clearResolutions() {
|
|
||||||
document.getElementById("video-resolution").innerHTML = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateExtraAudioInfo(type, data) {
|
|
||||||
console.log("Extra info type: " + type);
|
|
||||||
console.log("Extra info data: " + data);
|
|
||||||
|
|
||||||
var textToAdd = "";
|
|
||||||
if (type == "pls_more_url_available") {
|
|
||||||
for (i = 0; i < data.length; i++) {
|
|
||||||
textToAdd += data[i] + "<br>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementById("extra-audio-info").innerHTML = textToAdd;
|
|
||||||
document.getElementById("extra-audio-info-div").style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
loadChannelsInList();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,3 +1,116 @@
|
||||||
|
// Se espera en la URL este tipo de llamada .html?type={audio,video}&channel={url_a_reproducir}
|
||||||
|
function loadItem(from) {
|
||||||
|
var value;
|
||||||
|
if (from == "audio") {
|
||||||
|
value = document.getElementById("input-reproduccion-audio").value;
|
||||||
|
reproduceAudio(value);
|
||||||
|
} else if (from == "video") {
|
||||||
|
value = document.getElementById("input-reproduccion-video").value;
|
||||||
|
reproduceVideo(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reproduceVideo(channelToReproduce) {
|
||||||
|
console.log("Reproducing video: " + channelToReproduce);
|
||||||
|
if (channelToReproduce.includes("m3u8")) {
|
||||||
|
var divInfo = document.getElementById("video-player").childElementCount;
|
||||||
|
if (divInfo == 0) {
|
||||||
|
player = new Clappr.Player({
|
||||||
|
source: channelToReproduce,
|
||||||
|
parentId: '#video-player',
|
||||||
|
height: '500px',
|
||||||
|
width: '100%',
|
||||||
|
autoPlay: true,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Assume player instance is already created
|
||||||
|
player.configure({
|
||||||
|
source: channelToReproduce,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
clearResolutions();
|
||||||
|
getResolution(channelToReproduce, updateResolution);
|
||||||
|
}
|
||||||
|
|
||||||
|
ga('send', {
|
||||||
|
hitType: 'event',
|
||||||
|
eventCategory: 'Video',
|
||||||
|
eventAction: 'play',
|
||||||
|
eventLabel: channelToReproduce
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function reproduceAudio(channelToReproduce) {
|
||||||
|
if (channelToReproduce.includes("pls")) {
|
||||||
|
getURLsFromPLS(channelToReproduce, reproducePLSFromUrl);
|
||||||
|
} else {
|
||||||
|
reproduceAudioFromUrl(channelToReproduce);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function reproduceAudioFromUrl(channelToReproduce) {
|
||||||
|
console.log("Reproducing audio: " + channelToReproduce);
|
||||||
|
var audioSource = document.getElementById('audio-controller');
|
||||||
|
var audioPlayer = document.getElementById('audio-player');
|
||||||
|
|
||||||
|
audioPlayer.src = channelToReproduce;
|
||||||
|
audioSource.load();
|
||||||
|
audioSource.pause();
|
||||||
|
|
||||||
|
var playPromise = audioSource.play();
|
||||||
|
if (playPromise !== undefined) {
|
||||||
|
playPromise.then(function() {
|
||||||
|
// Automatic playback started!
|
||||||
|
}).catch(function(error) {
|
||||||
|
// Automatic playback failed.
|
||||||
|
// Show a UI element to let the user manually start playback.
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ga('send', {
|
||||||
|
hitType: 'event',
|
||||||
|
eventCategory: 'Audio',
|
||||||
|
eventAction: 'play',
|
||||||
|
eventLabel: channelToReproduce
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function reproducePLSFromUrl(data) {
|
||||||
|
reproduceAudioFromUrl(data[0]);
|
||||||
|
updateExtraAudioInfo("pls_more_url_available", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateResolution(resolutions) {
|
||||||
|
console.log("Resoluciones: " + resolutions);
|
||||||
|
|
||||||
|
for (i = 0; i < resolutions.length; i++) {
|
||||||
|
var resolutionToAdd = resolutions[i];
|
||||||
|
if (i < resolutions.length - 1){
|
||||||
|
resolutionToAdd += ", ";
|
||||||
|
}
|
||||||
|
document.getElementById("video-resolution").innerHTML += resolutionToAdd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearResolutions() {
|
||||||
|
document.getElementById("video-resolution").innerHTML = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateExtraAudioInfo(type, data) {
|
||||||
|
console.log("Extra info type: " + type);
|
||||||
|
console.log("Extra info data: " + data);
|
||||||
|
|
||||||
|
var textToAdd = "";
|
||||||
|
if (type == "pls_more_url_available") {
|
||||||
|
for (i = 0; i < data.length; i++) {
|
||||||
|
textToAdd += data[i] + "<br>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("extra-audio-info").innerHTML = textToAdd;
|
||||||
|
document.getElementById("extra-audio-info-div").style.display = "block";
|
||||||
|
}
|
||||||
|
|
||||||
function getURLsFromPLS(sUrl, fn_callback) {
|
function getURLsFromPLS(sUrl, fn_callback) {
|
||||||
$.get(sUrl, function(data) {
|
$.get(sUrl, function(data) {
|
||||||
$response = data.split("\n");
|
$response = data.split("\n");
|
||||||
|
@ -54,9 +167,34 @@ function getUrlParameter(sParam) {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check an URL is valid or broken
|
// Check an URL is valid or broken
|
||||||
// TODO: For streams if it works it keeps loading infinite time
|
// FIXME: For streams if it works it keeps loading infinite time
|
||||||
function checkIfWebsiteWorks(sUrl){
|
function checkIfWebsiteWorks(sUrl){
|
||||||
$.get(sUrl, function(data, status){
|
$.get(sUrl, function(data, status){
|
||||||
alert("Data: " + data + "\nStatus: " + status);
|
alert("Data: " + data + "\nStatus: " + status);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onChannelClick(channel){
|
||||||
|
channel = JSON.parse(channel);
|
||||||
|
reproduceVideo(channel['options'][0]['url'])
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadChannelsInList() {
|
||||||
|
fetch('http://91.121.64.179/tdt_project/output/channels.json')
|
||||||
|
.then(function(response) {
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(function(myJson) {
|
||||||
|
console.log(myJson);
|
||||||
|
nacionales = myJson[1];
|
||||||
|
|
||||||
|
var items = [];
|
||||||
|
$.each(nacionales["ambits"], function( ambit, ambit_val ) {
|
||||||
|
$.each(ambit_val["channels"], function( key, val ) {
|
||||||
|
items.push("<a href='javascript:onChannelClick("+ JSON.stringify(JSON.stringify(val)) + ")' class='list-group-item list-group-item-action'>" + val["name"] + "</a>")
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(items.join( "" )).appendTo(".channels-list");
|
||||||
|
});
|
||||||
}
|
}
|
|
@ -1,3 +1,10 @@
|
||||||
.container[data-container] {
|
.container[data-container] {
|
||||||
max-width: 100% !important;
|
max-width: 100% !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-group{
|
||||||
|
max-height: 70%;
|
||||||
|
overflow: scroll;
|
||||||
|
overflow-x: hidden;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
Loading…
Reference in a new issue