Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull #3

Merged
merged 4 commits into from
Mar 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions streamonitor/bot.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,14 @@ def getPlaylistVariants(self, url):
m3u8_doc = result.content.decode("utf-8")
variant_m3u8 = m3u8.loads(m3u8_doc)
for playlist in variant_m3u8.playlists:
resolution = playlist.stream_info.resolution if type(playlist.stream_info.resolution) is tuple else (0, 0)
sources.append(( playlist.uri, resolution ))
stream_info = playlist.stream_info
resolution = stream_info.resolution if type(stream_info.resolution) is tuple else (0, 0)
sources.append({
'url': playlist.uri,
'resolution': resolution,
'frame_rate': stream_info.frame_rate,
'bandwidth': stream_info.bandwidth
})

if not variant_m3u8.is_variant and len(sources) >= 1:
self.logger.warn("Not variant playlist, can't select resolution")
Expand All @@ -200,32 +206,29 @@ def getWantedResolutionPlaylist(self, url):
self.logger.error("No available sources")
return None

sources2 = []
for source in sources:
width, height = source[1]
width, height = source['resolution']
if width < height:
source += (width - WANTED_RESOLUTION,)
source['resolution_diff'] = width - WANTED_RESOLUTION
else:
source += (height - WANTED_RESOLUTION,)
sources2.append(source)
sources = sources2
source['resolution_diff'] = height - WANTED_RESOLUTION

sources.sort(key=lambda a: abs(a[2]))
sources.sort(key=lambda a: abs(a['resolution_diff']))
selected_source = None

if WANTED_RESOLUTION_PREFERENCE == 'exact':
if sources[0][2] == 0:
if sources[0]['resolution_diff'] == 0:
selected_source = sources[0]
elif WANTED_RESOLUTION_PREFERENCE == 'closest' or len(sources) == 1:
selected_source = sources[0]
elif WANTED_RESOLUTION_PREFERENCE == 'exact_or_least_higher':
for source in sources:
if source[2] >= 0:
if source['resolution_diff'] >= 0:
selected_source = source
break
elif WANTED_RESOLUTION_PREFERENCE == 'exact_or_highest_lower':
for source in sources:
if source[2] <= 0:
if source['resolution_diff'] <= 0:
selected_source = source
break
else:
Expand All @@ -236,9 +239,12 @@ def getWantedResolutionPlaylist(self, url):
self.logger.error("Couldn't select a resolution")
return None

if selected_source[1][1] != 0:
self.logger.info(f'Selected {selected_source[1][0]}x{selected_source[1][1]} resolution')
selected_source_url = selected_source[0]
if selected_source['resolution'][1] != 0:
frame_rate = ''
if selected_source['frame_rate'] is not None and selected_source['frame_rate'] != 0:
frame_rate = f" {selected_source['frame_rate']}fps"
self.logger.info(f"Selected {selected_source['resolution'][0]}x{selected_source['resolution'][1]}{frame_rate} resolution")
selected_source_url = selected_source['url']
if selected_source_url.startswith("https://"):
return selected_source_url
else:
Expand Down
9 changes: 8 additions & 1 deletion streamonitor/downloaders/ffmpeg.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import errno
import subprocess
import sys

import requests.cookies
from threading import Thread
from parameters import DEBUG
Expand Down Expand Up @@ -43,7 +45,12 @@ def execute():
try:
stdout = open(filename + '.stdout.log', 'w+') if DEBUG else subprocess.DEVNULL
stderr = open(filename + '.stderr.log', 'w+') if DEBUG else subprocess.DEVNULL
process = subprocess.Popen(args=cmd, stdin=subprocess.PIPE, stderr=stderr, stdout=stdout)
startupinfo = None
if sys.platform == "win32":
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
process = subprocess.Popen(
args=cmd, stdin=subprocess.PIPE, stderr=stderr, stdout=stdout, startupinfo=startupinfo)
except OSError as e:
if e.errno == errno.ENOENT:
self.logger.error('FFMpeg executable not found!')
Expand Down
9 changes: 7 additions & 2 deletions streamonitor/sites/myfreecams.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ class MyFreeCams(Bot):
def __init__(self, username):
super().__init__(username)
self.attrs = {}
self.videoUrl = None

def getVideoUrl(self, refresh=False):
if not refresh:
return self.videoUrl

def getVideoUrl(self):
if 'data-cam-preview-model-id-value' not in self.attrs:
return None

Expand Down Expand Up @@ -41,7 +45,8 @@ def getStatus(self):
params = doc.find(class_='campreview-link')
if params:
self.attrs = params.attrs
if self.getVideoUrl():
self.videoUrl = self.getVideoUrl(refresh=True)
if self.videoUrl:
return Bot.Status.PUBLIC
else:
return Bot.Status.PRIVATE
Expand Down
18 changes: 13 additions & 5 deletions streamonitor/sites/stripchat.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,28 @@ class StripChat(Bot):
site = 'StripChat'
siteslug = 'SC'

def __init__(self, username):
super().__init__(username)
self.vr = False

def getVideoUrl(self):
return self.getWantedResolutionPlaylist(None)

def getPlaylistVariants(self, url):
def formatUrl(auto):
return "https://edge-hls.{host}/hls/{id}/master/{id}{auto}.m3u8".format(
def formatUrl(master, auto):
return "https://edge-hls.{host}/hls/{id}{vr}/{master}/{id}{vr}{auto}.m3u8".format(
server=self.lastInfo["cam"]["viewServers"]["flashphoner-hls"],
host='doppiocdn.com',
id=self.lastInfo["cam"]["streamName"],
auto='_auto' if auto else '')
master='master' if master else '',
auto='_auto' if auto else '',
vr='_vr' if self.vr else '')

variants = []
variants.extend(super().getPlaylistVariants(formatUrl(False)))
variants.extend(super().getPlaylistVariants(formatUrl(True)))
variants.extend(super().getPlaylistVariants(formatUrl(True, False)))
variants.extend(super().getPlaylistVariants(formatUrl(True, True)))
variants.extend(super().getPlaylistVariants(formatUrl(False, True)))
variants.extend(super().getPlaylistVariants(formatUrl(False, False)))
return variants

def getStatus(self):
Expand Down
10 changes: 1 addition & 9 deletions streamonitor/sites/stripchat_vr.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from streamonitor.sites.stripchat import StripChat
from streamonitor.bot import Bot
from streamonitor.downloaders.fmp4s_wss import getVideoWSSVR


class StripChatVR(StripChat):
Expand All @@ -9,15 +8,8 @@ class StripChatVR(StripChat):

def __init__(self, username):
super().__init__(username)
self.getVideo = getVideoWSSVR
self.stopDownloadFlag = False

def getVideoUrl(self):
return "wss://s-{server}.{host}/{id}_vr_webxr?".format(
server=self.lastInfo["broadcastSettings"]["vrBroadcastServer"],
host='stripcdn.com',
id=self.lastInfo["cam"]["streamName"]
) + '&'.join([k + '=' + v for k, v in self.lastInfo['broadcastSettings']['vrCameraSettings'].items()])
self.vr = True

def getStatus(self):
status = super(StripChatVR, self).getStatus()
Expand Down