finished work with recorders
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
import multiprocessing
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -8,12 +9,18 @@ CHAT_DIVIDER = "<~|~>"
|
|||||||
|
|
||||||
class TwitchChatRecorder:
|
class TwitchChatRecorder:
|
||||||
is_running = False
|
is_running = False
|
||||||
|
chat_process = None
|
||||||
|
|
||||||
def __init__(self, api, debug=False):
|
def __init__(self, api, debug=False):
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.api = api
|
self.api = api
|
||||||
|
|
||||||
def run(self, streamer_name, output_file):
|
def run(self, streamer_name, output_file):
|
||||||
|
self.is_running = True
|
||||||
|
self.chat_process = multiprocessing.Process(target=self._record_chat, args=(streamer_name, output_file))
|
||||||
|
self.chat_process.start()
|
||||||
|
|
||||||
|
def _record_chat(self, streamer_name, output_file):
|
||||||
with open(output_file, "w") as stream:
|
with open(output_file, "w") as stream:
|
||||||
def on_message(twitch_msg):
|
def on_message(twitch_msg):
|
||||||
user, msg = self.parse_msg(twitch_msg)
|
user, msg = self.parse_msg(twitch_msg)
|
||||||
@@ -25,9 +32,21 @@ class TwitchChatRecorder:
|
|||||||
if self.debug:
|
if self.debug:
|
||||||
logger.info("Chat: %s", msg_line)
|
logger.info("Chat: %s", msg_line)
|
||||||
|
|
||||||
self.is_running = True
|
|
||||||
self.api.start_chat(streamer_name, on_message)
|
self.api.start_chat(streamer_name, on_message)
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
try:
|
||||||
|
if self.chat_process:
|
||||||
|
self.chat_process.terminate()
|
||||||
|
|
||||||
|
self.chat_process = None
|
||||||
|
logger.error("Chat stopped")
|
||||||
|
except BaseException as e:
|
||||||
|
logger.error("Unable to stop chat")
|
||||||
|
logger.error(e)
|
||||||
|
|
||||||
|
self.is_running = False
|
||||||
|
|
||||||
def parse_msg(self, msg):
|
def parse_msg(self, msg):
|
||||||
try:
|
try:
|
||||||
return msg[1:].split('!')[0], msg.split(":", 2)[2]
|
return msg[1:].split('!')[0], msg.split(":", 2)[2]
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import logging
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import sys
|
import sys
|
||||||
import threading
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from clipper.api import TwitchApi, TwitchStreamStatus
|
from clipper.api import TwitchApi, TwitchStreamStatus
|
||||||
@@ -22,21 +21,29 @@ class RecorderConfig:
|
|||||||
|
|
||||||
|
|
||||||
class Recorder:
|
class Recorder:
|
||||||
audio_thread = None
|
|
||||||
video_thread = None
|
|
||||||
|
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
self.config = config
|
self.config = config
|
||||||
self.api = TwitchApi(config.tw_client, config.tw_secret)
|
self.api = TwitchApi(config.tw_client, config.tw_secret)
|
||||||
self.streamer_folder = os.path.join(self.config.output_folder, self.config.tw_streamer)
|
self.streamer_folder = os.path.join(self.config.output_folder, self.config.tw_streamer)
|
||||||
self.video_recorder = TwitchVideoRecorder()
|
self.video_recorder = TwitchVideoRecorder()
|
||||||
self.chat_recorder = TwitchChatRecorder(self.api, debug=True)
|
self.chat_recorder = TwitchChatRecorder(self.api, debug=False)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
while True:
|
|
||||||
logger.info("Start watching streamer %s", self.config.tw_streamer)
|
logger.info("Start watching streamer %s", self.config.tw_streamer)
|
||||||
status = self.api.get_user_status(self.config.tw_streamer)
|
status = self.api.get_user_status(self.config.tw_streamer)
|
||||||
if status == TwitchStreamStatus.ONLINE:
|
|
||||||
|
while True:
|
||||||
|
if self.video_recorder.is_running or self.chat_recorder.is_running:
|
||||||
|
if not (self.video_recorder.is_running and self.chat_recorder.is_running):
|
||||||
|
self.video_recorder.stop()
|
||||||
|
self.chat_recorder.stop()
|
||||||
|
time.sleep(1)
|
||||||
|
continue
|
||||||
|
|
||||||
|
logger.info("Recording in progress. Wait 1m")
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
|
elif status == TwitchStreamStatus.ONLINE:
|
||||||
logger.info("Streamer %s is online. Start recording", self.config.tw_streamer)
|
logger.info("Streamer %s is online. Start recording", self.config.tw_streamer)
|
||||||
|
|
||||||
start_time = datetime.now()
|
start_time = datetime.now()
|
||||||
@@ -48,12 +55,11 @@ class Recorder:
|
|||||||
video_file = os.path.join(record_folder, "video.mp4")
|
video_file = os.path.join(record_folder, "video.mp4")
|
||||||
|
|
||||||
self.chat_recorder.run(self.config.tw_streamer, chat_file)
|
self.chat_recorder.run(self.config.tw_streamer, chat_file)
|
||||||
# self.video_recorder.run(file_template)
|
self.video_recorder.run(self.config.tw_streamer, video_file, quality="160p")
|
||||||
|
|
||||||
logger.info("Streamer %s has finished stream", self.config.tw_streamer)
|
time.sleep(5)
|
||||||
time.sleep(15)
|
|
||||||
|
|
||||||
if status == TwitchStreamStatus.OFFLINE:
|
elif status == TwitchStreamStatus.OFFLINE:
|
||||||
logger.info("Streamer %s is offline. Waiting for 300 sec", self.config.tw_streamer)
|
logger.info("Streamer %s is offline. Waiting for 300 sec", self.config.tw_streamer)
|
||||||
time.sleep(300)
|
time.sleep(300)
|
||||||
|
|
||||||
@@ -61,6 +67,6 @@ class Recorder:
|
|||||||
logger.critical("Error occurred. Exit", self.config.tw_streamer)
|
logger.critical("Error occurred. Exit", self.config.tw_streamer)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if status == TwitchStreamStatus.NOT_FOUND:
|
elif status == TwitchStreamStatus.NOT_FOUND:
|
||||||
logger.critical(f"Streamer %s not found, invalid streamer_name or typo", self.config.tw_streamer)
|
logger.critical(f"Streamer %s not found, invalid streamer_name or typo", self.config.tw_streamer)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|||||||
@@ -9,15 +9,25 @@ class TwitchVideoRecorder:
|
|||||||
refresh_timeout = 15
|
refresh_timeout = 15
|
||||||
streamlink_process = None
|
streamlink_process = None
|
||||||
|
|
||||||
def run(self, streamer_name, output_file, quality="480p"):
|
def run(self, streamer_name, output_file, quality="720p"):
|
||||||
|
self.is_running = True
|
||||||
self._record_stream(streamer_name, output_file, quality)
|
self._record_stream(streamer_name, output_file, quality)
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
|
try:
|
||||||
if self.streamlink_process:
|
if self.streamlink_process:
|
||||||
self.streamlink_process.kill()
|
self.streamlink_process.terminate()
|
||||||
|
|
||||||
|
self.streamlink_process = None
|
||||||
|
logger.error("Video stopped")
|
||||||
|
except BaseException as e:
|
||||||
|
logger.error("Unable to stop video")
|
||||||
|
logger.error(e)
|
||||||
|
|
||||||
|
self.is_running = False
|
||||||
|
|
||||||
def _record_stream(self, streamer_name, output_file, quality):
|
def _record_stream(self, streamer_name, output_file, quality):
|
||||||
# subprocess.call()
|
try:
|
||||||
self.streamlink_process = subprocess.Popen([
|
self.streamlink_process = subprocess.Popen([
|
||||||
"streamlink",
|
"streamlink",
|
||||||
"--twitch-disable-ads",
|
"--twitch-disable-ads",
|
||||||
@@ -27,4 +37,7 @@ class TwitchVideoRecorder:
|
|||||||
output_file
|
output_file
|
||||||
])
|
])
|
||||||
|
|
||||||
self.is_running = True
|
except BaseException as e:
|
||||||
|
logger.error("Unable to run streamlink")
|
||||||
|
logger.error(e)
|
||||||
|
self.is_running = False
|
||||||
|
|||||||
Reference in New Issue
Block a user