switch to requests, move playlist reader to utils, url quote, spellings
This commit is contained in:
parent
cc3c47dd94
commit
52a33d39c0
@ -17,16 +17,10 @@
|
|||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
import os
|
|
||||||
import socket
|
|
||||||
import ssl
|
|
||||||
import time
|
|
||||||
from urllib import request
|
|
||||||
|
|
||||||
from .filters.default import build_filtergraph
|
from .filters.default import build_filtergraph
|
||||||
from .utils import (MediaProbe, _playlist, gen_filler, get_date, get_delta,
|
from .utils import (MediaProbe, _playlist, gen_filler, get_date, get_delta,
|
||||||
get_float, get_time, messenger, stdin_args, timed_source,
|
get_float, get_time, messenger, read_playlist, stdin_args,
|
||||||
valid_json, validate_thread)
|
timed_source)
|
||||||
|
|
||||||
|
|
||||||
class GetSourceFromPlaylist:
|
class GetSourceFromPlaylist:
|
||||||
@ -37,6 +31,7 @@ class GetSourceFromPlaylist:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
self.list_date = get_date(True)
|
||||||
self.init_time = _playlist.start
|
self.init_time = _playlist.start
|
||||||
self.last_time = get_time('full_sec')
|
self.last_time = get_time('full_sec')
|
||||||
|
|
||||||
@ -49,15 +44,12 @@ class GetSourceFromPlaylist:
|
|||||||
self.last_time += self.total_playtime
|
self.last_time += self.total_playtime
|
||||||
|
|
||||||
self.last_mod_time = 0.0
|
self.last_mod_time = 0.0
|
||||||
self.json_file = None
|
|
||||||
self.clip_nodes = None
|
self.clip_nodes = None
|
||||||
self.src_cmd = None
|
self.src_cmd = None
|
||||||
self.probe = MediaProbe()
|
self.probe = MediaProbe()
|
||||||
self.filtergraph = []
|
self.filtergraph = []
|
||||||
self.first = True
|
self.first = True
|
||||||
self.last = False
|
self.last = False
|
||||||
self.list_date = get_date(True)
|
|
||||||
|
|
||||||
self.node = None
|
self.node = None
|
||||||
self.node_last = None
|
self.node_last = None
|
||||||
self.node_next = None
|
self.node_next = None
|
||||||
@ -66,49 +58,11 @@ class GetSourceFromPlaylist:
|
|||||||
self.seek = 0
|
self.seek = 0
|
||||||
self.out = 20
|
self.out = 20
|
||||||
self.duration = 20
|
self.duration = 20
|
||||||
self.ad = False
|
|
||||||
self.ad_last = False
|
|
||||||
self.ad_next = False
|
|
||||||
|
|
||||||
def get_playlist(self):
|
def get_playlist(self):
|
||||||
if stdin_args.playlist:
|
self.clip_nodes, self.last_mod_time = read_playlist(self.list_date,
|
||||||
self.json_file = stdin_args.playlist
|
self.last_mod_time,
|
||||||
else:
|
self.clip_nodes)
|
||||||
year, month, day = self.list_date.split('-')
|
|
||||||
self.json_file = os.path.join(
|
|
||||||
_playlist.path, year, month, self.list_date + '.json')
|
|
||||||
|
|
||||||
if '://' in self.json_file:
|
|
||||||
self.json_file = self.json_file.replace('\\', '/')
|
|
||||||
|
|
||||||
try:
|
|
||||||
req = request.urlopen(self.json_file,
|
|
||||||
timeout=1,
|
|
||||||
context=ssl._create_unverified_context())
|
|
||||||
b_time = req.headers['last-modified']
|
|
||||||
temp_time = time.strptime(b_time, "%a, %d %b %Y %H:%M:%S %Z")
|
|
||||||
mod_time = time.mktime(temp_time)
|
|
||||||
|
|
||||||
if mod_time > self.last_mod_time:
|
|
||||||
self.clip_nodes = valid_json(req)
|
|
||||||
self.last_mod_time = mod_time
|
|
||||||
messenger.info('Open: ' + self.json_file)
|
|
||||||
validate_thread(self.clip_nodes)
|
|
||||||
except (request.URLError, socket.timeout):
|
|
||||||
self.eof_handling('Get playlist from url failed!', False)
|
|
||||||
|
|
||||||
elif os.path.isfile(self.json_file):
|
|
||||||
# check last modification from playlist
|
|
||||||
mod_time = os.path.getmtime(self.json_file)
|
|
||||||
if mod_time > self.last_mod_time:
|
|
||||||
with open(self.json_file, 'r', encoding='utf-8') as f:
|
|
||||||
self.clip_nodes = valid_json(f)
|
|
||||||
|
|
||||||
self.last_mod_time = mod_time
|
|
||||||
messenger.info('Open: ' + self.json_file)
|
|
||||||
validate_thread(self.clip_nodes)
|
|
||||||
else:
|
|
||||||
self.clip_nodes = None
|
|
||||||
|
|
||||||
def get_input(self):
|
def get_input(self):
|
||||||
self.src_cmd, self.seek, self.out, self.next_playlist = timed_source(
|
self.src_cmd, self.seek, self.out, self.next_playlist = timed_source(
|
||||||
@ -145,11 +99,8 @@ class GetSourceFromPlaylist:
|
|||||||
self.last_mod_time = 0.0
|
self.last_mod_time = 0.0
|
||||||
self.last_time = _playlist.start - 1
|
self.last_time = _playlist.start - 1
|
||||||
|
|
||||||
def eof_handling(self, message, fill, duration=None):
|
def eof_handling(self, fill, duration=None):
|
||||||
self.seek = 0.0
|
self.seek = 0.0
|
||||||
self.ad = False
|
|
||||||
|
|
||||||
messenger.error(message)
|
|
||||||
|
|
||||||
if duration:
|
if duration:
|
||||||
self.out = duration
|
self.out = duration
|
||||||
@ -177,8 +128,8 @@ class GetSourceFromPlaylist:
|
|||||||
|
|
||||||
def peperation_task(self, index):
|
def peperation_task(self, index):
|
||||||
# call functions in order to prepare source and filter
|
# call functions in order to prepare source and filter
|
||||||
self.src = self.node['source']
|
self.probe.load(self.node.get('source'))
|
||||||
self.probe.load(self.src)
|
self.src = self.probe.src
|
||||||
|
|
||||||
self.get_input()
|
self.get_input()
|
||||||
self.last_and_next_node(index)
|
self.last_and_next_node(index)
|
||||||
@ -190,8 +141,9 @@ class GetSourceFromPlaylist:
|
|||||||
self.get_playlist()
|
self.get_playlist()
|
||||||
|
|
||||||
if self.clip_nodes is None:
|
if self.clip_nodes is None:
|
||||||
self.eof_handling(
|
self.node = {'in': 0, 'out': 30, 'duration': 30}
|
||||||
f'No valid playlist:\n{self.json_file}', True, 30)
|
messenger.error('clip_nodes are empty')
|
||||||
|
self.eof_handling(True, 30)
|
||||||
yield self.src_cmd + self.filtergraph
|
yield self.src_cmd + self.filtergraph
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -231,10 +183,12 @@ class GetSourceFromPlaylist:
|
|||||||
return None
|
return None
|
||||||
elif self.begin == self.init_time:
|
elif self.begin == self.init_time:
|
||||||
# no clip was played, generate dummy
|
# no clip was played, generate dummy
|
||||||
self.eof_handling('Playlist is empty!', False)
|
messenger.error('Playlist is empty!')
|
||||||
|
self.eof_handling(False)
|
||||||
else:
|
else:
|
||||||
# playlist is not long enough, play filler
|
# playlist is not long enough, play filler
|
||||||
self.eof_handling('Playlist is not long enough!', True)
|
messenger.error('Playlist is not long enough!')
|
||||||
|
self.eof_handling(True)
|
||||||
|
|
||||||
if self.src_cmd is not None:
|
if self.src_cmd is not None:
|
||||||
yield self.src_cmd + self.filtergraph
|
yield self.src_cmd + self.filtergraph
|
||||||
|
@ -27,6 +27,8 @@ import smtplib
|
|||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
import time
|
||||||
|
import urllib
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from datetime import date, datetime, timedelta
|
from datetime import date, datetime, timedelta
|
||||||
from email.mime.multipart import MIMEMultipart
|
from email.mime.multipart import MIMEMultipart
|
||||||
@ -39,6 +41,7 @@ from subprocess import STDOUT, CalledProcessError, check_output
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
from types import SimpleNamespace
|
from types import SimpleNamespace
|
||||||
|
|
||||||
|
import requests
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
# path to user define configs
|
# path to user define configs
|
||||||
@ -550,6 +553,8 @@ class MediaProbe:
|
|||||||
self.video = []
|
self.video = []
|
||||||
|
|
||||||
if self.src and self.src.split('://')[0] in self.remote_source:
|
if self.src and self.src.split('://')[0] in self.remote_source:
|
||||||
|
url = self.src.split('://')
|
||||||
|
self.src = f'{url[0]}://{urllib.parse.quote(url[1])}'
|
||||||
self.is_remote = True
|
self.is_remote = True
|
||||||
else:
|
else:
|
||||||
self.is_remote = False
|
self.is_remote = False
|
||||||
@ -747,7 +752,7 @@ def validate_thread(clip_nodes):
|
|||||||
|
|
||||||
if probe.is_remote:
|
if probe.is_remote:
|
||||||
if not probe.video[0]:
|
if not probe.video[0]:
|
||||||
missing.append(f'Stream not exist: "{source}"')
|
missing.append(f'Remote file not exist: "{source}"')
|
||||||
elif not os.path.isfile(source):
|
elif not os.path.isfile(source):
|
||||||
missing.append(f'File not exist: "{source}"')
|
missing.append(f'File not exist: "{source}"')
|
||||||
|
|
||||||
@ -863,7 +868,7 @@ def src_or_dummy(probe, src, dur, seek, out):
|
|||||||
if probe.is_remote and probe.video[0]:
|
if probe.is_remote and probe.video[0]:
|
||||||
if seek > 0.0:
|
if seek > 0.0:
|
||||||
messenger.warning(
|
messenger.warning(
|
||||||
f'Seek in live source "{src}" not supported!')
|
f'Seek in remote source "{src}" not supported!')
|
||||||
return ['-i', src] + set_length(86400.0, seek, out)
|
return ['-i', src] + set_length(86400.0, seek, out)
|
||||||
elif src and os.path.isfile(src):
|
elif src and os.path.isfile(src):
|
||||||
if out > dur:
|
if out > dur:
|
||||||
@ -972,6 +977,51 @@ def handle_list_end(probe, new_length, src, begin, dur, seek, out):
|
|||||||
return src_cmd, seek, new_out, new_playlist
|
return src_cmd, seek, new_out, new_playlist
|
||||||
|
|
||||||
|
|
||||||
|
def read_playlist(list_date, modification_time, clip_nodes):
|
||||||
|
"""
|
||||||
|
read playlists from remote url or local file
|
||||||
|
and give his nodes and modification time back
|
||||||
|
"""
|
||||||
|
|
||||||
|
if stdin_args.playlist:
|
||||||
|
json_file = stdin_args.playlist
|
||||||
|
else:
|
||||||
|
year, month, day = list_date.split('-')
|
||||||
|
json_file = os.path.join(_playlist.path, year, month,
|
||||||
|
f'{list_date}.json')
|
||||||
|
|
||||||
|
if '://' in json_file:
|
||||||
|
json_file = json_file.replace('\\', '/')
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = requests.get(json_file, timeout=1, verify=False)
|
||||||
|
b_time = result.headers['last-modified']
|
||||||
|
temp_time = time.strptime(b_time, "%a, %d %b %Y %H:%M:%S %Z")
|
||||||
|
mod_time = time.mktime(temp_time)
|
||||||
|
|
||||||
|
if mod_time > modification_time:
|
||||||
|
if isinstance(result.json(), dict):
|
||||||
|
clip_nodes = result.json()
|
||||||
|
modification_time = mod_time
|
||||||
|
messenger.info('Open: ' + json_file)
|
||||||
|
validate_thread(clip_nodes)
|
||||||
|
except (requests.exceptions.ConnectionError, socket.timeout):
|
||||||
|
messenger.error(f'No valid playlist from url: {json_file}')
|
||||||
|
|
||||||
|
elif os.path.isfile(json_file):
|
||||||
|
# check last modification from playlist
|
||||||
|
mod_time = os.path.getmtime(json_file)
|
||||||
|
if mod_time > modification_time:
|
||||||
|
with open(json_file, 'r', encoding='utf-8') as f:
|
||||||
|
clip_nodes = valid_json(f)
|
||||||
|
|
||||||
|
modification_time = mod_time
|
||||||
|
messenger.info('Open: ' + json_file)
|
||||||
|
validate_thread(clip_nodes)
|
||||||
|
|
||||||
|
return clip_nodes, modification_time
|
||||||
|
|
||||||
|
|
||||||
def timed_source(probe, src, begin, dur, seek, out, first, last):
|
def timed_source(probe, src, begin, dur, seek, out, first, last):
|
||||||
"""
|
"""
|
||||||
prepare input clip
|
prepare input clip
|
||||||
|
Loading…
x
Reference in New Issue
Block a user