1
0
mirror of https://github.com/fHDHR/fHDHR_NextPVR.git synced 2025-12-06 14:46:58 -05:00

Compare commits

..

No commits in common. "e7282522b5d7b9af181d8c180667ad0c04a09a56" and "b6ef8b13aed41f0c1825de8ab849ece04bad3a4f" have entirely different histories.

19 changed files with 144 additions and 203 deletions

View File

@ -1,21 +1,14 @@
{ {
"streaming":{
"bytes_per_read": {
"value": 1152000,
"config_file": true,
"config_web": true
},
"quality": {
"value": "none",
"config_file": true,
"config_web": true
}
},
"ffmpeg":{ "ffmpeg":{
"path":{ "path":{
"value": "ffmpeg", "value": "ffmpeg",
"config_file": true, "config_file": true,
"config_web": true "config_web": true
},
"bytes_per_read":{
"value": 1152000,
"config_file": true,
"config_web": true
} }
}, },
"vlc":{ "vlc":{
@ -23,6 +16,18 @@
"value": "cvlc", "value": "cvlc",
"config_file": true, "config_file": true,
"config_web": true "config_web": true
},
"bytes_per_read":{
"value": 1152000,
"config_file": true,
"config_web": true
}
},
"direct_stream":{
"chunksize":{
"value": 1048576,
"config_file": true,
"config_web": true
} }
} }
} }

View File

@ -21,8 +21,6 @@ class fHDHR_INT_OBJ():
self.api = fHDHR_API_URLs(settings, self.web) self.api = fHDHR_API_URLs(settings, self.web)
self.threads = {}
class fHDHR_OBJ(): class fHDHR_OBJ():

View File

@ -1,6 +1,8 @@
import os import os
import sys import sys
import argparse import argparse
import time
import threading
from fHDHR import fHDHR_VERSION, fHDHR_OBJ from fHDHR import fHDHR_VERSION, fHDHR_OBJ
import fHDHR.exceptions import fHDHR.exceptions
@ -36,24 +38,28 @@ def run(settings, logger, db, script_dir, fHDHR_web, origin, alternative_epg):
try: try:
# Start Flask Thread fhdhr.logger.info("HTTP Server Starting")
fhdhrweb.start() fhdhr_web = threading.Thread(target=fhdhrweb.run)
fhdhr_web.start()
# Start SSDP Thread
if settings.dict["fhdhr"]["discovery_address"]: if settings.dict["fhdhr"]["discovery_address"]:
fhdhr.device.ssdp.start() fhdhr.logger.info("SSDP Server Starting")
fhdhr_ssdp = threading.Thread(target=fhdhr.device.ssdp.run)
fhdhr_ssdp.start()
# Start EPG Thread
if settings.dict["epg"]["method"]: if settings.dict["epg"]["method"]:
fhdhr.device.epg.start() fhdhr.logger.info("EPG Update Thread Starting")
fhdhr_epg = threading.Thread(target=fhdhr.device.epg.run)
fhdhr_epg.start()
# Perform some actions now that HTTP Server is running # Perform some actions now that HTTP Server is running
fhdhr.logger.info("Waiting 3 seconds to send startup tasks trigger.")
time.sleep(3)
fhdhr.api.get("/api/startup_tasks") fhdhr.api.get("/api/startup_tasks")
# wait forever # wait forever
while fhdhr.threads["flask"].is_alive(): while True:
restart_code = "restart" time.sleep(3600)
return restart_code
except KeyboardInterrupt: except KeyboardInterrupt:
return ERR_CODE_NO_RESTART return ERR_CODE_NO_RESTART
@ -86,10 +92,7 @@ def main(script_dir, fHDHR_web, origin, alternative_epg):
try: try:
args = build_args_parser() args = build_args_parser()
while True: return start(args, script_dir, fHDHR_web, origin, alternative_epg)
returned_code = start(args, script_dir, fHDHR_web, origin, alternative_epg)
if returned_code not in ["restart"]:
return returned_code
except KeyboardInterrupt: except KeyboardInterrupt:
print("\n\nInterrupted") print("\n\nInterrupted")
return ERR_CODE return ERR_CODE

View File

@ -111,8 +111,8 @@ class Channels():
return [self.list[x].dict for x in list(self.list.keys())] return [self.list[x].dict for x in list(self.list.keys())]
def get_channel_stream(self, stream_args): def get_channel_stream(self, channel_number):
return self.origin.get_channel_stream(self.get_channel_dict("number", stream_args["channel"]), stream_args) return self.origin.get_channel_stream(self.get_channel_dict("number", channel_number))
def get_channel_dict(self, keyfind, valfind): def get_channel_dict(self, keyfind, valfind):
return self.get_channel_obj(keyfind, valfind).dict return self.get_channel_obj(keyfind, valfind).dict

View File

@ -1,7 +1,6 @@
import os import os
import time import time
import datetime import datetime
import threading
from fHDHR.tools import channel_sort from fHDHR.tools import channel_sort
@ -40,8 +39,6 @@ class EPG():
self.epg_update_url = "/api/epg?method=update" self.epg_update_url = "/api/epg?method=update"
self.fhdhr.threads["epg"] = threading.Thread(target=self.run)
def clear_epg_cache(self, method=None): def clear_epg_cache(self, method=None):
if not method: if not method:
@ -281,31 +278,20 @@ class EPG():
programguide[cnum]["listing"][prog_index]["thumbnail"] = programguide[cnum]["thumbnail"] programguide[cnum]["listing"][prog_index]["thumbnail"] = programguide[cnum]["thumbnail"]
prog_index += 1 prog_index += 1
# Get Totals
total_channels = len(list(programguide.keys()))
total_programs = 0
# Sort the channels # Sort the channels
sorted_channel_list = channel_sort(list(programguide.keys())) sorted_channel_list = channel_sort(list(programguide.keys()))
sorted_chan_guide = {} sorted_chan_guide = {}
for channel in sorted_channel_list: for channel in sorted_channel_list:
total_programs += len(programguide[cnum]["listing"])
sorted_chan_guide[channel] = programguide[channel] sorted_chan_guide[channel] = programguide[channel]
self.epgdict[method] = sorted_chan_guide self.epgdict[method] = sorted_chan_guide
self.fhdhr.db.set_fhdhr_value("epg_dict", method, programguide) self.fhdhr.db.set_fhdhr_value("epg_dict", method, programguide)
self.fhdhr.db.set_fhdhr_value("update_time", method, time.time()) self.fhdhr.db.set_fhdhr_value("update_time", method, time.time())
self.fhdhr.logger.info("Wrote %s EPG cache. %s Programs for %s Channels" % (epgtypename, total_programs, total_channels)) self.fhdhr.logger.info("Wrote " + epgtypename + " EPG cache.")
def start(self):
self.fhdhr.logger.info("EPG Update Thread Starting")
self.fhdhr.threads["epg"].start()
def stop(self):
self.fhdhr.logger.info("EPG Update Thread Stopping")
def run(self): def run(self):
time.sleep(1800) time.sleep(1800)
try:
while True: while True:
for epg_method in self.epg_methods: for epg_method in self.epg_methods:
last_update_time = self.fhdhr.db.get_fhdhr_value("update_time", epg_method) last_update_time = self.fhdhr.db.get_fhdhr_value("update_time", epg_method)
@ -317,5 +303,5 @@ class EPG():
if updatetheepg: if updatetheepg:
self.fhdhr.api.get("%s&source=%s" % (self.epg_update_url, epg_method)) self.fhdhr.api.get("%s&source=%s" % (self.epg_update_url, epg_method))
time.sleep(1800) time.sleep(1800)
except KeyboardInterrupt:
self.stop() pass

View File

@ -2,7 +2,6 @@
import socket import socket
import struct import struct
import time import time
import threading
from .ssdp_detect import fHDHR_Detect from .ssdp_detect import fHDHR_Detect
from .rmg_ssdp import RMG_SSDP from .rmg_ssdp import RMG_SSDP
@ -16,8 +15,6 @@ class SSDPServer():
self.detect_method = fHDHR_Detect(fhdhr) self.detect_method = fHDHR_Detect(fhdhr)
self.fhdhr.threads["ssdp"] = threading.Thread(target=self.run)
if (self.fhdhr.config.dict["fhdhr"]["discovery_address"] and if (self.fhdhr.config.dict["fhdhr"]["discovery_address"] and
self.fhdhr.config.dict["ssdp"]["enabled"]): self.fhdhr.config.dict["ssdp"]["enabled"]):
self.setup_ssdp() self.setup_ssdp()
@ -35,21 +32,6 @@ class SSDPServer():
self.do_alive() self.do_alive()
self.m_search() self.m_search()
def start(self):
self.fhdhr.logger.info("SSDP Server Starting")
self.fhdhr.threads["ssdp"].start()
def stop(self):
self.fhdhr.logger.info("SSDP Server Stopping")
self.sock.close()
def run(self):
while True:
data, address = self.sock.recvfrom(1024)
self.on_recv(data, address)
self.do_alive()
self.stop()
def do_alive(self, forcealive=False): def do_alive(self, forcealive=False):
send_alive = False send_alive = False
@ -150,6 +132,15 @@ class SSDPServer():
return data.encode("utf-8") return data.encode("utf-8")
def run(self):
try:
while True:
data, address = self.sock.recvfrom(1024)
self.on_recv(data, address)
self.do_alive()
except KeyboardInterrupt:
self.sock.close()
def setup_ssdp(self): def setup_ssdp(self):
self.sock = None self.sock = None

View File

@ -91,21 +91,17 @@ class Tuners():
def get_stream_info(self, stream_args): def get_stream_info(self, stream_args):
stream_info = self.channels.get_channel_stream(stream_args) stream_args["channelUri"] = self.channels.get_channel_stream(str(stream_args["channel"]))
if not stream_info: if not stream_args["channelUri"]:
raise TunerError("806 - Tune Failed") raise TunerError("806 - Tune Failed")
if isinstance(stream_info, str): if stream_args["channelUri"].startswith("udp://"):
stream_info = {"url": stream_info}
stream_args["stream_info"] = stream_info
if stream_args["stream_info"]["url"].startswith("udp://"):
stream_args["true_content_type"] = "video/mpeg" stream_args["true_content_type"] = "video/mpeg"
stream_args["content_type"] = "video/mpeg" stream_args["content_type"] = "video/mpeg"
else: else:
channel_stream_url_headers = self.fhdhr.web.session.head(stream_args["stream_info"]["url"]).headers channelUri_headers = self.fhdhr.web.session.head(stream_args["channelUri"]).headers
stream_args["true_content_type"] = channel_stream_url_headers['Content-Type'] stream_args["true_content_type"] = channelUri_headers['Content-Type']
if stream_args["true_content_type"].startswith(tuple(["application/", "text/"])): if stream_args["true_content_type"].startswith(tuple(["application/", "text/"])):
stream_args["content_type"] = "video/mpeg" stream_args["content_type"] = "video/mpeg"

View File

@ -14,7 +14,7 @@ class Direct_M3U8_Stream():
self.stream_args = stream_args self.stream_args = stream_args
self.tuner = tuner self.tuner = tuner
self.bytes_per_read = int(self.fhdhr.config.dict["streaming"]["bytes_per_read"]) self.chunksize = int(self.fhdhr.config.dict["direct_stream"]['chunksize'])
def get(self): def get(self):
@ -23,14 +23,14 @@ class Direct_M3U8_Stream():
self.fhdhr.logger.info("Detected stream URL is m3u8: %s" % self.stream_args["true_content_type"]) self.fhdhr.logger.info("Detected stream URL is m3u8: %s" % self.stream_args["true_content_type"])
channel_stream_url = self.stream_args["stream_info"]["url"] channelUri = self.stream_args["channelUri"]
while True: while True:
self.fhdhr.logger.info("Opening m3u8 for reading %s" % channel_stream_url) self.fhdhr.logger.info("Opening m3u8 for reading %s" % channelUri)
videoUrlM3u = m3u8.load(channel_stream_url) videoUrlM3u = m3u8.load(channelUri)
if len(videoUrlM3u.playlists): if len(videoUrlM3u.playlists):
self.fhdhr.logger.info("%s m3u8 varients found" % len(videoUrlM3u.playlists)) self.fhdhr.logger.info("%s m3u8 varients found" % len(videoUrlM3u.playlists))
channel_stream_url = videoUrlM3u.playlists[0].absolute_uri channelUri = videoUrlM3u.playlists[0].absolute_uri
else: else:
break break
@ -42,7 +42,7 @@ class Direct_M3U8_Stream():
while self.tuner.tuner_lock.locked(): while self.tuner.tuner_lock.locked():
playlist = m3u8.load(channel_stream_url) playlist = m3u8.load(channelUri)
segments = playlist.segments segments = playlist.segments
if len(played_chunk_urls): if len(played_chunk_urls):

View File

@ -11,16 +11,16 @@ class Direct_Stream():
self.stream_args = stream_args self.stream_args = stream_args
self.tuner = tuner self.tuner = tuner
self.bytes_per_read = int(self.fhdhr.config.dict["streaming"]["bytes_per_read"]) self.chunksize = int(self.fhdhr.config.dict["direct_stream"]['chunksize'])
def get(self): def get(self):
if not self.stream_args["duration"] == 0: if not self.stream_args["duration"] == 0:
self.stream_args["time_end"] = self.stream_args["duration"] + time.time() self.stream_args["time_end"] = self.stream_args["duration"] + time.time()
self.fhdhr.logger.info("Direct Stream of %s URL: %s" % (self.stream_args["true_content_type"], self.stream_args["stream_info"]["url"])) self.fhdhr.logger.info("Direct Stream of %s URL: %s" % (self.stream_args["true_content_type"], self.stream_args["channelUri"]))
req = self.fhdhr.web.session.get(self.stream_args["stream_info"]["url"], stream=True) req = self.fhdhr.web.session.get(self.stream_args["channelUri"], stream=True)
def generate(): def generate():
@ -30,7 +30,7 @@ class Direct_Stream():
while self.tuner.tuner_lock.locked(): while self.tuner.tuner_lock.locked():
for chunk in req.iter_content(chunk_size=self.bytes_per_read): for chunk in req.iter_content(chunk_size=self.chunksize):
if (not self.stream_args["duration"] == 0 and if (not self.stream_args["duration"] == 0 and
not time.time() < self.stream_args["time_end"]): not time.time() < self.stream_args["time_end"]):

View File

@ -11,7 +11,7 @@ class FFMPEG_Stream():
self.stream_args = stream_args self.stream_args = stream_args
self.tuner = tuner self.tuner = tuner
self.bytes_per_read = int(self.fhdhr.config.dict["streaming"]["bytes_per_read"]) self.bytes_per_read = int(self.fhdhr.config.dict["ffmpeg"]["bytes_per_read"])
self.ffmpeg_command = self.ffmpeg_command_assemble(stream_args) self.ffmpeg_command = self.ffmpeg_command_assemble(stream_args)
def get(self): def get(self):
@ -48,7 +48,7 @@ class FFMPEG_Stream():
def ffmpeg_command_assemble(self, stream_args): def ffmpeg_command_assemble(self, stream_args):
ffmpeg_command = [ ffmpeg_command = [
self.fhdhr.config.dict["ffmpeg"]["path"], self.fhdhr.config.dict["ffmpeg"]["path"],
"-i", stream_args["stream_info"]["url"], "-i", stream_args["channelUri"],
] ]
ffmpeg_command.extend(self.ffmpeg_duration(stream_args)) ffmpeg_command.extend(self.ffmpeg_duration(stream_args))
ffmpeg_command.extend(self.transcode_profiles(stream_args)) ffmpeg_command.extend(self.transcode_profiles(stream_args))

View File

@ -11,7 +11,7 @@ class VLC_Stream():
self.stream_args = stream_args self.stream_args = stream_args
self.tuner = tuner self.tuner = tuner
self.bytes_per_read = int(self.fhdhr.config.dict["streaming"]["bytes_per_read"]) self.bytes_per_read = int(self.fhdhr.config.dict["vlc"]["bytes_per_read"])
self.vlc_command = self.vlc_command_assemble(stream_args) self.vlc_command = self.vlc_command_assemble(stream_args)
def get(self): def get(self):
@ -49,7 +49,7 @@ class VLC_Stream():
def vlc_command_assemble(self, stream_args): def vlc_command_assemble(self, stream_args):
vlc_command = [ vlc_command = [
self.fhdhr.config.dict["vlc"]["path"], self.fhdhr.config.dict["vlc"]["path"],
"-I", "dummy", stream_args["stream_info"]["url"], "-I", "dummy", stream_args["channelUri"],
] ]
vlc_command.extend(self.vlc_duration(stream_args)) vlc_command.extend(self.vlc_duration(stream_args))
vlc_command.extend(self.vlc_loglevel()) vlc_command.extend(self.vlc_loglevel())

View File

@ -17,7 +17,7 @@ class Tuner():
self.tuner_lock = threading.Lock() self.tuner_lock = threading.Lock()
self.set_off_status() self.set_off_status()
self.chanscan_url = "/api/channels?method=scan" self.chanscan_url = "%s/api/channels?method=scan"
self.close_url = "/api/tuners?method=close&tuner=%s" % str(self.number) self.close_url = "/api/tuners?method=close&tuner=%s" % str(self.number)
def channel_scan(self, grabbed=False): def channel_scan(self, grabbed=False):
@ -88,7 +88,7 @@ class Tuner():
"method": stream_args["method"], "method": stream_args["method"],
"accessed": [stream_args["accessed"]], "accessed": [stream_args["accessed"]],
"channel": stream_args["channel"], "channel": stream_args["channel"],
"proxied_url": stream_args["stream_info"]["url"], "proxied_url": stream_args["channelUri"],
"time_start": datetime.datetime.utcnow(), "time_start": datetime.datetime.utcnow(),
"downloaded": 0 "downloaded": 0
} }

View File

@ -36,8 +36,8 @@ class OriginServiceWrapper():
def get_channels(self): def get_channels(self):
return self.channels.get_channels() return self.channels.get_channels()
def get_channel_stream(self, chandict, stream_args): def get_channel_stream(self, chandict):
return self.channels.get_channel_stream(chandict, stream_args) return self.channels.get_channel_stream(chandict)
def update_epg(self, channels): def update_epg(self, channels):
return self.epg.update_epg(channels) return self.epg.update_epg(channels)

View File

@ -7,5 +7,5 @@ class OriginChannels_StandIN():
def get_channels(self): def get_channels(self):
return [] return []
def get_channel_stream(self, chandict, stream_args): def get_channel_stream(self, chandict):
return None return None

View File

@ -1,7 +1,5 @@
from gevent.pywsgi import WSGIServer from gevent.pywsgi import WSGIServer
from flask import Flask, request, session from flask import Flask, request, session
import threading
import uuid
from .pages import fHDHR_Pages from .pages import fHDHR_Pages
from .files import fHDHR_Files from .files import fHDHR_Files
@ -25,7 +23,6 @@ class fHDHR_HTTP_Server():
self.fhdhr.logger.info("Loading Flask.") self.fhdhr.logger.info("Loading Flask.")
self.fhdhr.app = Flask("fHDHR", template_folder=self.template_folder) self.fhdhr.app = Flask("fHDHR", template_folder=self.template_folder)
self.instance_id = str(uuid.uuid4())
# Allow Internal API Usage # Allow Internal API Usage
self.fhdhr.app.testing = True self.fhdhr.app.testing = True
@ -66,24 +63,11 @@ class fHDHR_HTTP_Server():
self.fhdhr.app.after_request(self.after_request) self.fhdhr.app.after_request(self.after_request)
self.fhdhr.app.before_first_request(self.before_first_request) self.fhdhr.app.before_first_request(self.before_first_request)
self.fhdhr.threads["flask"] = threading.Thread(target=self.run)
def start(self):
self.fhdhr.logger.info("Flask HTTP Thread Starting")
self.fhdhr.threads["flask"].start()
def stop(self):
self.fhdhr.logger.info("Flask HTTP Thread Stopping")
self.http.stop()
def before_first_request(self): def before_first_request(self):
self.fhdhr.logger.info("HTTP Server Online.") self.fhdhr.logger.info("HTTP Server Online.")
def before_request(self): def before_request(self):
session["session_id"] = str(uuid.uuid4())
session["instance_id"] = self.instance_id
session["is_internal_api"] = self.detect_internal_api(request) session["is_internal_api"] = self.detect_internal_api(request)
if session["is_internal_api"]: if session["is_internal_api"]:
self.fhdhr.logger.debug("Client is using internal API call.") self.fhdhr.logger.debug("Client is using internal API call.")
@ -100,8 +84,6 @@ class fHDHR_HTTP_Server():
session["tuner_used"] = None session["tuner_used"] = None
session["restart"] = False
self.fhdhr.logger.debug("Client %s requested %s Opening" % (request.method, request.path)) self.fhdhr.logger.debug("Client %s requested %s Opening" % (request.method, request.path))
def after_request(self, response): def after_request(self, response):
@ -114,10 +96,7 @@ class fHDHR_HTTP_Server():
# tuner.close() # tuner.close()
self.fhdhr.logger.debug("Client %s requested %s Closing" % (request.method, request.path)) self.fhdhr.logger.debug("Client %s requested %s Closing" % (request.method, request.path))
if not session["restart"]:
return response return response
else:
return self.stop()
def detect_internal_api(self, request): def detect_internal_api(self, request):
user_agent = request.headers.get('User-Agent') user_agent = request.headers.get('User-Agent')
@ -186,8 +165,8 @@ class fHDHR_HTTP_Server():
self.http = WSGIServer(self.fhdhr.api.address_tuple, self.http = WSGIServer(self.fhdhr.api.address_tuple,
self.fhdhr.app.wsgi_app, self.fhdhr.app.wsgi_app,
log=self.fhdhr.logger) log=self.fhdhr.logger)
try: try:
self.http.serve_forever() self.http.serve_forever()
self.stop() except KeyboardInterrupt:
except AttributeError: self.http.stop()
self.fhdhr.logger.info("HTTP Server Offline")

View File

@ -1,4 +1,4 @@
from flask import request, redirect, session from flask import request, redirect
import urllib.parse import urllib.parse
@ -34,11 +34,6 @@ class Settings():
self.fhdhr.config.write(config_section, config_name, config_value) self.fhdhr.config.write(config_section, config_name, config_value)
elif method == "restart":
instance_id = request.args.get('instance_id', default=None, type=str)
if instance_id == session["instance_id"]:
session["restart"] = True
if redirect_url: if redirect_url:
return redirect(redirect_url + "?retmessage=" + urllib.parse.quote("%s Success" % method)) return redirect(redirect_url + "?retmessage=" + urllib.parse.quote("%s Success" % method))
else: else:

View File

@ -14,10 +14,6 @@ class Tuners():
def __init__(self, fhdhr): def __init__(self, fhdhr):
self.fhdhr = fhdhr self.fhdhr = fhdhr
self.quality = self.fhdhr.config.dict["streaming"]["quality"]
if self.quality:
self.quality = str(self.quality).lower()
def __call__(self, *args): def __call__(self, *args):
return self.get(*args) return self.get(*args)
@ -54,11 +50,8 @@ class Tuners():
duration = request.args.get('duration', default=0, type=int) duration = request.args.get('duration', default=0, type=int)
transcode = request.args.get('transcode', default=self.quality, type=str) transcode = request.args.get('transcode', default=None, type=str)
valid_transcode_types = [ valid_transcode_types = [None, "heavy", "mobile", "internet720", "internet480", "internet360", "internet240"]
None, "high", "medium", "low"
"heavy", "mobile", "internet720", "internet480", "internet360", "internet240"
]
if transcode not in valid_transcode_types: if transcode not in valid_transcode_types:
response = Response("Service Unavailable", status=503) response = Response("Service Unavailable", status=503)
response.headers["X-fHDHR-Error"] = "802 - Unknown Transcode Profile" response.headers["X-fHDHR-Error"] = "802 - Unknown Transcode Profile"
@ -105,6 +98,9 @@ class Tuners():
tuner.set_status(stream_args) tuner.set_status(stream_args)
session["tuner_used"] = tunernum session["tuner_used"] = tunernum
if stream_args["method"] == "direct":
return Response(tuner.get_stream(stream_args, tuner), content_type=stream_args["content_type"], direct_passthrough=True)
elif stream_args["method"] in ["ffmpeg", "vlc"]:
return Response(stream_with_context(tuner.get_stream(stream_args, tuner)), mimetype=stream_args["content_type"]) return Response(stream_with_context(tuner.get_stream(stream_args, tuner)), mimetype=stream_args["content_type"])
elif method == "close": elif method == "close":

View File

@ -4,12 +4,7 @@
<h4 style="text-align: center;">fHDHR Settings</h4> <h4 style="text-align: center;">fHDHR Settings</h4>
<h4 style="text-align: center;">Some Settings will require a manual restart.</h4> <h4 style="text-align: center;">Settings will require a manual restart.</h4>
<div style="text-align: center;">
<button onclick="OpenLink('/api/settings?method=restart&instance_id={{ session["instance_id"] }}&redirect=%2Fsettings')">Restart fHDHR</a></button><p> Note: This may take some time, and you will have to refresh your page.</p>
</div>
<br>
{% for config_section in list(web_settings_dict.keys()) %} {% for config_section in list(web_settings_dict.keys()) %}

View File

@ -50,7 +50,7 @@ class OriginChannels():
channel_list.append(clean_station_item) channel_list.append(clean_station_item)
return channel_list return channel_list
def get_channel_stream(self, chandict, stream_args): def get_channel_stream(self, chandict):
streamurl = ('%s%s:%s/live?channel_id=%s&client=%s' % streamurl = ('%s%s:%s/live?channel_id=%s&client=%s' %
("https://" if self.fhdhr.config.dict["origin"]["ssl"] else "http://", ("https://" if self.fhdhr.config.dict["origin"]["ssl"] else "http://",
self.fhdhr.config.dict["origin"]["address"], self.fhdhr.config.dict["origin"]["address"],
@ -58,7 +58,4 @@ class OriginChannels():
str(chandict["origin_id"]), str(chandict["origin_id"]),
"fhdhr_" + str(chandict["origin_number"]), "fhdhr_" + str(chandict["origin_number"]),
)) ))
return streamurl
stream_info = {"url": streamurl}
return stream_info