cast js
This commit is contained in:
parent
7ec157cf62
commit
da8cfa9222
74
data/www/js/cast-url.js
Normal file
74
data/www/js/cast-url.js
Normal file
@ -0,0 +1,74 @@
|
||||
var applicationID = '81585E3E';
|
||||
var namespace = 'urn:x-cast:com.jrk.obscreen';
|
||||
var session = null;
|
||||
|
||||
if (!chrome.cast || !chrome.cast.isAvailable) {
|
||||
setTimeout(initializeCastApi, 1000);
|
||||
}
|
||||
|
||||
function initializeCastApi() {
|
||||
var sessionRequest = new chrome.cast.SessionRequest(applicationID);
|
||||
var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
|
||||
sessionListener,
|
||||
receiverListener);
|
||||
|
||||
chrome.cast.initialize(apiConfig, onInitSuccess, onError);
|
||||
}
|
||||
|
||||
function onInitSuccess() {
|
||||
// console.log('onInitSuccess');
|
||||
}
|
||||
|
||||
function onError(message) {
|
||||
console.error('onError: ' + JSON.stringify(message));
|
||||
}
|
||||
|
||||
function onSuccess(message) {
|
||||
// console.log('onSuccess: ' + JSON.stringify(message));
|
||||
}
|
||||
|
||||
// function onStopAppSuccess() {
|
||||
// console.log('onStopAppSuccess');
|
||||
// }
|
||||
|
||||
function sessionListener(e) {
|
||||
console.log('New session ID: ' + e.sessionId);
|
||||
session = e;
|
||||
session.addUpdateListener(sessionUpdateListener);
|
||||
}
|
||||
|
||||
function sessionUpdateListener(isAlive) {
|
||||
console.log((isAlive ? 'Session Updated' : 'Session Removed') + ': ' + session.sessionId);
|
||||
if (!isAlive) {
|
||||
session = null;
|
||||
}
|
||||
}
|
||||
|
||||
function receiverListener(e) {
|
||||
// Due to API changes just ignore this.
|
||||
}
|
||||
|
||||
function sendMessage(message) {
|
||||
if (session != null) {
|
||||
session.sendMessage(namespace, message, onSuccess.bind(this, message), onError);
|
||||
} else {
|
||||
chrome.cast.requestSession(function (e) {
|
||||
session = e;
|
||||
sessionListener(e);
|
||||
session.sendMessage(namespace, message, onSuccess.bind(this, message), onError);
|
||||
}, onError);
|
||||
}
|
||||
}
|
||||
|
||||
// function stopApp() {
|
||||
// session.stop(onStopAppSuccess, onError);
|
||||
// }
|
||||
|
||||
jQuery(function ($) {
|
||||
$(document).on('click', '.cast-url', function () {
|
||||
sendMessage({
|
||||
type: 'load',
|
||||
url: $('#' + $(this).attr('data-target-id')).val()
|
||||
});
|
||||
});
|
||||
});
|
||||
13
data/www/js/lib/cast-sender.js
Normal file
13
data/www/js/lib/cast-sender.js
Normal file
@ -0,0 +1,13 @@
|
||||
(function(){/*
|
||||
|
||||
Copyright The Closure Library Authors.
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
'use strict';var l=function(){var a=h,b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}},m=this||self,n=/^[\w+/_-]+[=]{0,2}$/,p=null,q=function(a){return(a=a.querySelector&&a.querySelector("script[nonce]"))&&(a=a.nonce||a.getAttribute("nonce"))&&n.test(a)?a:""},r=function(a,b){function e(){}e.prototype=b.prototype;a.i=b.prototype;a.prototype=new e;a.prototype.constructor=a;a.h=function(c,g,k){for(var f=Array(arguments.length-2),d=2;d<arguments.length;d++)f[d-2]=arguments[d];
|
||||
return b.prototype[g].apply(c,f)}},t=function(a){return a};function u(a){if(Error.captureStackTrace)Error.captureStackTrace(this,u);else{var b=Error().stack;b&&(this.stack=b)}a&&(this.message=String(a))}r(u,Error);u.prototype.name="CustomError";var v=function(a,b){a=a.split("%s");for(var e="",c=a.length-1,g=0;g<c;g++)e+=a[g]+(g<b.length?b[g]:"%s");u.call(this,e+a[c])};r(v,u);v.prototype.name="AssertionError";var w=function(a,b){throw new v("Failure"+(a?": "+a:""),Array.prototype.slice.call(arguments,1));};var x;var A=function(a,b){this.g=b===z?a:""};A.prototype.toString=function(){return this.g+""};var z={};var B=function(){var a=window.navigator.userAgent.match(/Chrome\/([0-9]+)/);return a?parseInt(a[1],10):0},C=function(a){return!!document.currentScript&&(-1!=document.currentScript.src.indexOf("?"+a)||-1!=document.currentScript.src.indexOf("&"+a))},D=function(){return"function"==typeof window.__onGCastApiAvailable?window.__onGCastApiAvailable:null},F=function(a){a.length?E(a.shift(),function(){F(a)}):G()},H=function(a){return"chrome-extension://"+a+"/cast_sender.js"},E=function(a,b,e){var c=document.createElement("script");
|
||||
c.onerror=b;e&&(c.onload=e);if(void 0===x)if(b=null,(e=m.trustedTypes)&&e.createPolicy){try{b=e.createPolicy("goog#html",{createHTML:t,createScript:t,createScriptURL:t})}catch(y){m.console&&m.console.error(y.message)}x=b}else x=b;a=(b=x)?b.createScriptURL(a):a;a=new A(a,z);a:{try{var g=c&&c.ownerDocument,k=g&&(g.defaultView||g.parentWindow);k=k||m;if(k.Element&&k.Location){var f=k;break a}}catch(y){}f=null}if(f&&"undefined"!=typeof f.HTMLScriptElement&&(!c||!(c instanceof f.HTMLScriptElement)&&(c instanceof
|
||||
f.Location||c instanceof f.Element))){f=typeof c;if("object"==f&&null!=c||"function"==f)try{var d=c.constructor.displayName||c.constructor.name||Object.prototype.toString.call(c)}catch(y){d="<object could not be stringified>"}else d=void 0===c?"undefined":null===c?"null":typeof c;w("Argument is not a %s (or a non-Element, non-Location mock); got: %s","HTMLScriptElement",d)}a instanceof A&&a.constructor===A?d=a.g:(d=typeof a,w("expected object of type TrustedResourceUrl, got '"+a+"' of type "+("object"!=
|
||||
d?d:a?Array.isArray(a)?"array":d:"null")),d="type_error:TrustedResourceUrl");c.src=d;(d=c.ownerDocument&&c.ownerDocument.defaultView)&&d!=m?d=q(d.document):(null===p&&(p=q(m.document)),d=p);d&&c.setAttribute("nonce",d);(document.head||document.documentElement).appendChild(c)},I=function(){var a=B(),b=[];if(1<a){var e=a-1;b.push("https://www.gstatic.com/eureka/clank/"+a+"/cast_sender.js");b.push("https://www.gstatic.com/eureka/clank/"+e+"/cast_sender.js")}return b},G=function(){var a=D();a&&a(!1,"No cast extension found")},
|
||||
K=function(){if(J){var a=2,b=D(),e=function(){a--;0==a&&b&&b(!0)};window.__onGCastApiAvailable=e;E("https://www.gstatic.com/cast/sdk/libs/sender/1.0/cast_framework.js",G,e)}},J=C("loadCastFramework")||C("loadCastApplicationFramework"),L=["pkedcjkdefgpdelpbcmbmeomcjbeemfm","enhhojjnijigcajfphajepfemndkmdlo"];if(0<=window.navigator.userAgent.indexOf("Android")&&0<=window.navigator.userAgent.indexOf("Chrome/")&&window.navigator.presentation){if(60<=B()){K();var M=I();M.push("https://www.gstatic.com/eureka/clank/cast_sender.js");F(M)}}else if(!window.chrome||!window.navigator.presentation||0<=window.navigator.userAgent.indexOf("Edge"))G();else if(89<=B()){K();var N=I(),O=N.push,P=O.apply,h=L.map(H),Q;if(h instanceof Array)Q=h;else{var R,S="undefined"!=typeof Symbol&&Symbol.iterator&&h[Symbol.iterator];R=S?S.call(h):
|
||||
{next:l()};for(var T,U=[];!(T=R.next()).done;)U.push(T.value);Q=U}P.call(O,N,Q);N.push("https://www.gstatic.com/eureka/clank/cast_sender.js");F(N)}else K(),F(L.map(H));}).call(this);
|
||||
|
||||
@ -40,62 +40,62 @@ jQuery(document).ready(function ($) {
|
||||
$icon.removeClass('fa-pause').addClass('fa-play');
|
||||
}
|
||||
});
|
||||
//
|
||||
// $(document).on('click', '.cast-scan', function () {
|
||||
// showModal('modal-playlist-cast-scan');
|
||||
// const $modal = $('.modal-playlist-cast-scan:visible');
|
||||
// const $holder = $modal.find('.cast-devices');
|
||||
// const $loading = $modal.find('.loading');
|
||||
//
|
||||
// $loading.removeClass('hidden');
|
||||
// $holder.removeClass('hidden');
|
||||
// $holder.html('');
|
||||
// $loading.html($loading.attr('data-loading'));
|
||||
//
|
||||
// $.ajax({
|
||||
// method: 'GET',
|
||||
// url: route_cast_scan,
|
||||
// headers: {'Content-Type': 'application/json'},
|
||||
// success: function (response) {
|
||||
// $loading.addClass('hidden')
|
||||
//
|
||||
// for (let i = 0; i < response.devices.length; i++) {
|
||||
// const device = response.devices[i];
|
||||
// $holder.append($('<li><a href="javascript:void(0)" class="cast-device" data-id="' + device.friendly_name + '"><i class="fa fa-brands fa-chromecast"></i>' + device.friendly_name + '</a></li>'));
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
$(document).on('click', '.cast-scan', function () {
|
||||
showModal('modal-playlist-cast-scan');
|
||||
const $modal = $('.modal-playlist-cast-scan:visible');
|
||||
const $holder = $modal.find('.cast-devices');
|
||||
const $loading = $modal.find('.loading');
|
||||
|
||||
$loading.removeClass('hidden');
|
||||
$holder.removeClass('hidden');
|
||||
$holder.html('');
|
||||
$loading.html($loading.attr('data-loading'));
|
||||
|
||||
$.ajax({
|
||||
method: 'GET',
|
||||
url: route_cast_scan,
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
success: function (response) {
|
||||
$loading.addClass('hidden')
|
||||
|
||||
for (let i = 0; i < response.devices.length; i++) {
|
||||
const device = response.devices[i];
|
||||
$holder.append($('<li><a href="javascript:void(0)" class="cast-device" data-id="' + device.friendly_name + '"><i class="fa fa-brands fa-chromecast"></i>' + device.friendly_name + '</a></li>'));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('click', '.cast-device', function () {
|
||||
const $modal = $('.modal-playlist-cast-scan:visible');
|
||||
const $holder = $modal.find('.cast-devices');
|
||||
const $loading = $modal.find('.loading');
|
||||
|
||||
$holder.addClass('hidden');
|
||||
$loading.removeClass('hidden');
|
||||
$loading.html($loading.attr('data-casting'));
|
||||
|
||||
const id = $(this).attr('data-id');
|
||||
|
||||
$.ajax({
|
||||
url: route_cast_url,
|
||||
method: 'POST',
|
||||
data: JSON.stringify({
|
||||
device: id,
|
||||
url: $('#playlist-preview-url').val()
|
||||
}),
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
success: function (response) {
|
||||
$loading.addClass('hidden');
|
||||
hideModal();
|
||||
},
|
||||
error: function () {
|
||||
$loading.addClass('hidden');
|
||||
$holder.removeClass('hidden');
|
||||
}
|
||||
});
|
||||
});
|
||||
// $(document).on('click', '.cast-device', function () {
|
||||
// const $modal = $('.modal-playlist-cast-scan:visible');
|
||||
// const $holder = $modal.find('.cast-devices');
|
||||
// const $loading = $modal.find('.loading');
|
||||
//
|
||||
// $holder.addClass('hidden');
|
||||
// $loading.removeClass('hidden');
|
||||
// $loading.html($loading.attr('data-casting'));
|
||||
//
|
||||
// const id = $(this).attr('data-id');
|
||||
//
|
||||
// $.ajax({
|
||||
// url: route_cast_url,
|
||||
// method: 'POST',
|
||||
// data: JSON.stringify({
|
||||
// device: id,
|
||||
// url: $('#playlist-preview-url').val()
|
||||
// }),
|
||||
// headers: {'Content-Type': 'application/json'},
|
||||
// success: function (response) {
|
||||
// $loading.addClass('hidden');
|
||||
// hideModal();
|
||||
// },
|
||||
// error: function () {
|
||||
// $loading.addClass('hidden');
|
||||
// $holder.removeClass('hidden');
|
||||
// }
|
||||
// });
|
||||
// });
|
||||
|
||||
main();
|
||||
});
|
||||
|
||||
@ -11,75 +11,75 @@
|
||||
align-self: stretch;
|
||||
color: $gscale6;
|
||||
}
|
||||
|
||||
.modal-playlist-cast-scan {
|
||||
h2 {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.alert {
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 20px;
|
||||
display: block;
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
a {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
color: $gscaleF;
|
||||
animation-duration: 2s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-name: blinkfade;
|
||||
}
|
||||
|
||||
ul.cast-devices {
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
list-style: none;
|
||||
border-bottom: 1px solid $gscale2;
|
||||
border-radius: $baseRadius;
|
||||
|
||||
a {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
padding: 20px 15px;
|
||||
color: $gscaleF;
|
||||
align-self: stretch;
|
||||
|
||||
i {
|
||||
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $gscale2;
|
||||
}
|
||||
}
|
||||
|
||||
li:last-child {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//.modal-playlist-cast-scan {
|
||||
// h2 {
|
||||
// text-align: left;
|
||||
// }
|
||||
//
|
||||
// .alert {
|
||||
// padding: 10px;
|
||||
// font-size: 12px;
|
||||
// margin-bottom: 20px;
|
||||
// display: block;
|
||||
// text-align: center;
|
||||
//
|
||||
// i {
|
||||
// margin-right: 5px;
|
||||
// }
|
||||
//
|
||||
// a {
|
||||
// margin: 0;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// .loading {
|
||||
// color: $gscaleF;
|
||||
// animation-duration: 2s;
|
||||
// animation-iteration-count: infinite;
|
||||
// animation-name: blinkfade;
|
||||
// }
|
||||
//
|
||||
// ul.cast-devices {
|
||||
// list-style: none;
|
||||
// margin: 0;
|
||||
// padding: 0;
|
||||
//
|
||||
// li {
|
||||
// display: flex;
|
||||
// flex-direction: row;
|
||||
// justify-content: flex-start;
|
||||
// align-items: center;
|
||||
// list-style: none;
|
||||
// border-bottom: 1px solid $gscale2;
|
||||
// border-radius: $baseRadius;
|
||||
//
|
||||
// a {
|
||||
// flex: 1;
|
||||
// display: flex;
|
||||
// flex-direction: row;
|
||||
// justify-content: flex-start;
|
||||
// align-items: center;
|
||||
// padding: 20px 15px;
|
||||
// color: $gscaleF;
|
||||
// align-self: stretch;
|
||||
//
|
||||
// i {
|
||||
//
|
||||
// margin-right: 10px;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// &:hover {
|
||||
// background: $gscale2;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// li:last-child {
|
||||
// border: none;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
.modal-slide {
|
||||
h2 {
|
||||
|
||||
42
docker/nginx/nginx.conf
Normal file
42
docker/nginx/nginx.conf
Normal file
@ -0,0 +1,42 @@
|
||||
user nginx;
|
||||
worker_processes 4;
|
||||
|
||||
error_log /var/log/nginx/error.log warn;
|
||||
pid /var/run/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
access_log /var/log/nginx/access.log;
|
||||
sendfile on;
|
||||
keepalive_timeout 65;
|
||||
client_max_body_size 200G;
|
||||
|
||||
autoindex on;
|
||||
|
||||
server {
|
||||
root /var/www/html/public;
|
||||
listen 80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
|
||||
ssl_certificate /ssl/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /ssl/ssl-cert-snakeoil.key;
|
||||
|
||||
location / {
|
||||
proxy_connect_timeout 60;
|
||||
proxy_read_timeout 60;
|
||||
proxy_send_timeout 60;
|
||||
proxy_intercept_errors on;
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://localhost:5000;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,8 @@
|
||||
flask==2.3.3
|
||||
flask-restx==1.3.0
|
||||
pychromecast==13.1.0
|
||||
python-dotenv
|
||||
cron-descriptor
|
||||
waitress
|
||||
flask-login
|
||||
pysqlite3
|
||||
psutil
|
||||
zeroconf
|
||||
@ -10,8 +10,8 @@ class CoreController(ObController):
|
||||
def register(self):
|
||||
self._app.add_url_rule('/manifest.json', 'manifest', self.manifest, methods=['GET'])
|
||||
self._app.add_url_rule('/favicon.ico', 'favicon', self.favicon, methods=['GET'])
|
||||
self._app.add_url_rule('/cast-scan', 'cast_scan', self.cast_scan, methods=['GET'])
|
||||
self._app.add_url_rule('/cast-url', 'cast_url', self.cast_url, methods=['POST'])
|
||||
# self._app.add_url_rule('/cast-scan', 'cast_scan', self.cast_scan, methods=['GET'])
|
||||
# self._app.add_url_rule('/cast-url', 'cast_url', self.cast_url, methods=['POST'])
|
||||
|
||||
def manifest(self):
|
||||
with open("{}/manifest.jinja.json".format(self.get_template_dir()), 'r') as file:
|
||||
@ -24,14 +24,14 @@ class CoreController(ObController):
|
||||
def favicon(self):
|
||||
return send_file("{}/favicon.ico".format(self.get_web_dir()), mimetype='image/x-icon')
|
||||
|
||||
def cast_scan(self):
|
||||
return jsonify({
|
||||
'devices': fetch_friendly_names(discovery_timeout=5)
|
||||
})
|
||||
|
||||
def cast_url(self):
|
||||
data = request.get_json()
|
||||
success = cast_url(friendly_name=data.get('device'), url=data.get('url'), discovery_timeout=5)
|
||||
# def cast_scan(self):
|
||||
# return jsonify({
|
||||
# 'devices': fetch_friendly_names(discovery_timeout=5)
|
||||
# })
|
||||
#
|
||||
# def cast_url(self):
|
||||
# data = request.get_json()
|
||||
# success = cast_url(friendly_name=data.get('device'), url=data.get('url'), discovery_timeout=5)
|
||||
|
||||
return jsonify({
|
||||
'success': success
|
||||
|
||||
@ -1,69 +1,69 @@
|
||||
import time
|
||||
import pychromecast
|
||||
import zeroconf
|
||||
import logging
|
||||
|
||||
from pychromecast.discovery import stop_discovery
|
||||
from pychromecast import CastBrowser, SimpleCastListener, get_chromecast_from_host, Chromecast
|
||||
from pychromecast.controllers import BaseController
|
||||
from typing import Optional
|
||||
|
||||
|
||||
APPLICATION_ID = '81585E3E'
|
||||
|
||||
|
||||
class CastController(BaseController):
|
||||
def __init__(self):
|
||||
super(CastController, self).__init__("urn:x-cast:com.jrk.obscreen")
|
||||
|
||||
def load_url(self, url: str):
|
||||
self.send_message({
|
||||
'url': url,
|
||||
'type': 'load'
|
||||
})
|
||||
|
||||
|
||||
def _discover(discovery_timeout: int = 5):
|
||||
zconf = zeroconf.Zeroconf()
|
||||
browser = pychromecast.CastBrowser(pychromecast.SimpleCastListener(), zconf)
|
||||
browser.start_discovery()
|
||||
time.sleep(discovery_timeout)
|
||||
stop_discovery(browser)
|
||||
|
||||
return browser
|
||||
|
||||
|
||||
def fetch_friendly_names(discovery_timeout: int = 5):
|
||||
return [{"friendly_name": cast_info.friendly_name} for device, cast_info in _discover(discovery_timeout).devices.items()]
|
||||
|
||||
|
||||
def fetch_chromecast(friendly_name: str, discovery_timeout: int = 5) -> Optional[Chromecast]:
|
||||
for uuid, cast_info in _discover(discovery_timeout).devices.items():
|
||||
if cast_info.friendly_name == friendly_name:
|
||||
try:
|
||||
return get_chromecast_from_host((cast_info.host, cast_info.port, uuid, cast_info.model_name, cast_info.friendly_name))
|
||||
except:
|
||||
pass
|
||||
|
||||
logging.info("No chromecast found for friendly_name {}".format(friendly_name))
|
||||
return None
|
||||
|
||||
|
||||
def cast_url(friendly_name: str, url: str, discovery_timeout: int = 5) -> bool:
|
||||
chromecast = fetch_chromecast(friendly_name, discovery_timeout)
|
||||
|
||||
if not chromecast:
|
||||
logging.info("Can't instantiate Chromecast {}".format(friendly_name))
|
||||
return False
|
||||
|
||||
chromecast.wait()
|
||||
chromecast.quit_app()
|
||||
time.sleep(2)
|
||||
|
||||
cast_controller = CastController()
|
||||
chromecast.register_handler(cast_controller)
|
||||
chromecast.start_app(APPLICATION_ID)
|
||||
time.sleep(2)
|
||||
cast_controller.load_url(url)
|
||||
|
||||
return True
|
||||
# import time
|
||||
# import pychromecast
|
||||
# import zeroconf
|
||||
# import logging
|
||||
#
|
||||
# from pychromecast.discovery import stop_discovery
|
||||
# from pychromecast import CastBrowser, SimpleCastListener, get_chromecast_from_host, Chromecast
|
||||
# from pychromecast.controllers import BaseController
|
||||
# from typing import Optional
|
||||
#
|
||||
#
|
||||
# APPLICATION_ID = '81585E3E'
|
||||
#
|
||||
#
|
||||
# class CastController(BaseController):
|
||||
# def __init__(self):
|
||||
# super(CastController, self).__init__("urn:x-cast:com.jrk.obscreen")
|
||||
#
|
||||
# def load_url(self, url: str):
|
||||
# self.send_message({
|
||||
# 'url': url,
|
||||
# 'type': 'load'
|
||||
# })
|
||||
#
|
||||
#
|
||||
# def _discover(discovery_timeout: int = 5):
|
||||
# zconf = zeroconf.Zeroconf()
|
||||
# browser = pychromecast.CastBrowser(pychromecast.SimpleCastListener(), zconf)
|
||||
# browser.start_discovery()
|
||||
# time.sleep(discovery_timeout)
|
||||
# stop_discovery(browser)
|
||||
#
|
||||
# return browser
|
||||
#
|
||||
#
|
||||
# def fetch_friendly_names(discovery_timeout: int = 5):
|
||||
# return [{"friendly_name": cast_info.friendly_name} for device, cast_info in _discover(discovery_timeout).devices.items()]
|
||||
#
|
||||
#
|
||||
# def fetch_chromecast(friendly_name: str, discovery_timeout: int = 5) -> Optional[Chromecast]:
|
||||
# for uuid, cast_info in _discover(discovery_timeout).devices.items():
|
||||
# if cast_info.friendly_name == friendly_name:
|
||||
# try:
|
||||
# return get_chromecast_from_host((cast_info.host, cast_info.port, uuid, cast_info.model_name, cast_info.friendly_name))
|
||||
# except:
|
||||
# pass
|
||||
#
|
||||
# logging.info("No chromecast found for friendly_name {}".format(friendly_name))
|
||||
# return None
|
||||
#
|
||||
#
|
||||
# def cast_url(friendly_name: str, url: str, discovery_timeout: int = 5) -> bool:
|
||||
# chromecast = fetch_chromecast(friendly_name, discovery_timeout)
|
||||
#
|
||||
# if not chromecast:
|
||||
# logging.info("Can't instantiate Chromecast {}".format(friendly_name))
|
||||
# return False
|
||||
#
|
||||
# chromecast.wait()
|
||||
# chromecast.quit_app()
|
||||
# time.sleep(2)
|
||||
#
|
||||
# cast_controller = CastController()
|
||||
# chromecast.register_handler(cast_controller)
|
||||
# chromecast.start_app(APPLICATION_ID)
|
||||
# time.sleep(2)
|
||||
# cast_controller.load_url(url)
|
||||
#
|
||||
# return True
|
||||
|
||||
@ -103,9 +103,12 @@
|
||||
<a href="{{ preview_url }}" class="btn btn-info" target="_blank">
|
||||
<i class="fa-solid fa-up-right-from-square"></i>
|
||||
</a>
|
||||
<button type="button" class="btn btn-neutral cast-scan">
|
||||
<button type="button" class="btn btn-neutral cast-url chrome-only hidden" data-target-id="playlist-preview-url">
|
||||
<i class="fa fa-brands fa-chromecast"></i>
|
||||
</button>
|
||||
{# <button type="button" class="btn btn-neutral cast-scan">#}
|
||||
{# <i class="fa fa-brands fa-chromecast"></i>#}
|
||||
{# </button>#}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -46,6 +46,21 @@
|
||||
}
|
||||
var contents = {{ json_dumps(contents) | safe }}
|
||||
</script>
|
||||
<script>
|
||||
jQuery(function($) {
|
||||
if (typeof chrome !== 'undefined') {
|
||||
$('.chrome-only').removeClass('hidden');
|
||||
|
||||
var script_sender = document.createElement('script');
|
||||
script_sender.src = "{{ STATIC_PREFIX }}js/lib/cast-sender.js";
|
||||
document.body.appendChild(script_sender);
|
||||
|
||||
var script_caster = document.createElement('script');
|
||||
script_caster.src = "{{ STATIC_PREFIX }}js/cast-url.js";
|
||||
document.body.appendChild(script_caster);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/jquery-explr-1.4.js"></script>
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/jquery-ui.min.js"></script>
|
||||
<script src="{{ STATIC_PREFIX }}js/lib/flatpickr.min.js"></script>
|
||||
@ -129,7 +144,7 @@
|
||||
<div class="modals-outer">
|
||||
<div class="modals-inner">
|
||||
{% include 'playlist/modal/add.jinja.html' %}
|
||||
{% include 'playlist/modal/cast-scan.jinja.html' %}
|
||||
{# {% include 'playlist/modal/cast-scan.jinja.html' %}#}
|
||||
|
||||
{% with is_notification=True %}{% include 'slideshow/slides/modal/edit.jinja.html' %}{% endwith %}
|
||||
{% with is_notification=False %}{% include 'slideshow/slides/modal/edit.jinja.html' %}{% endwith %}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user