added record of current service

This commit is contained in:
DYefremov
2020-03-07 18:33:51 +03:00
parent 8a1496a84c
commit ee29659739
3 changed files with 143 additions and 10 deletions

View File

@@ -1,6 +1,8 @@
import os
import sys
from datetime import datetime
from app.commons import run_task, log
from app.commons import run_task, log, _DATE_FORMAT
class Player:
@@ -103,5 +105,61 @@ class Player:
self._player.set_fullscreen(full)
class Recorder:
__VLC_REC_INSTANCE = None
_CMD = "sout=#std{{access=file,mux=ts,dst={}{}_{}.ts}}"
def __init__(self):
try:
from app.tools import vlc
from app.tools.vlc import EventType
except OSError as e:
log("{}: Load library error: {}".format(__class__.__name__, e))
raise ImportError
else:
self._is_record = False
args = "--quiet {}".format("" if sys.platform == "darwin" else "--no-xlib")
self._recorder = vlc.Instance(args).media_player_new()
@classmethod
def get_instance(cls):
if not cls.__VLC_REC_INSTANCE:
cls.__VLC_REC_INSTANCE = Recorder()
return cls.__VLC_REC_INSTANCE
@run_task
def record(self, url, path, name):
if self._recorder:
self._recorder.stop()
os.makedirs(os.path.dirname(path), exist_ok=True)
d_now = datetime.now().strftime(_DATE_FORMAT)
media = self._recorder.get_instance().media_new(url, self._CMD.format(path, name, d_now))
media.get_mrl()
self._recorder.set_media(media)
self._is_record = True
self._recorder.play()
log("Record started {}".format(d_now))
@run_task
def stop(self):
self._recorder.stop()
self._is_record = False
log("Recording stopped.")
def is_record(self):
return self._is_record
@run_task
def release(self):
if self._recorder:
self._recorder.stop()
self._recorder.release()
self._is_record = False
log("Recording stopped. Releasing...")
if __name__ == "__main__":
pass

View File

@@ -17,7 +17,7 @@ from app.eparser.enigma.bouquets import BqServiceType
from app.eparser.iptv import export_to_m3u
from app.eparser.neutrino.bouquets import BqType
from app.settings import SettingsType, Settings, SettingsException
from app.tools.media import Player
from app.tools.media import Player, Recorder
from app.ui.epg_dialog import EpgDialog
from app.ui.transmitter import LinksTransmitter
from .backup import BackupDialog, backup_data, clear_data_path
@@ -69,6 +69,7 @@ class Application(Gtk.Application):
super().__init__(flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE, **kwargs)
# Adding command line options
self.add_main_option("log", ord("l"), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "", None)
self.add_main_option("record", ord("r"), GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "", None)
self._handlers = {"on_close_app": self.on_close_app,
"on_resize": self.on_resize,
@@ -172,6 +173,8 @@ class Application(Gtk.Application):
self._player = None
self._full_screen = False
self._drawing_area_xid = None
# Record
self._recorder = None
# http api
self._http_api = None
self._fav_click_mode = None
@@ -226,6 +229,9 @@ class Application(Gtk.Application):
self._tv_count_label = builder.get_object("tv_count_label")
self._radio_count_label = builder.get_object("radio_count_label")
self._data_count_label = builder.get_object("data_count_label")
self._app_info_box.bind_property("visible", self._save_header_button, "visible", 4)
self._signal_level_bar.bind_property("visible", builder.get_object("play_current_service_button"), "visible")
self._signal_level_bar.bind_property("visible", builder.get_object("record_button"), "visible")
self._receiver_info_box.bind_property("visible", self._http_status_image, "visible", 4)
self._receiver_info_box.bind_property("visible", self._signal_box, "visible")
# Force ctrl press event for view. Multiple selections in lists only with Space key(as in file managers)!!!
@@ -264,7 +270,8 @@ class Application(Gtk.Application):
self._player_box.bind_property("visible", self._profile_combo_box, "sensitive", 4)
self._fav_view.bind_property("sensitive", self._player_prev_button, "sensitive")
self._fav_view.bind_property("sensitive", self._player_next_button, "sensitive")
self._signal_level_bar.bind_property("visible", builder.get_object("play_current_service_button"), "visible")
# Record
self._record_image = builder.get_object("record_button_image")
# Enabling events for the drawing area
self._player_drawing_area.set_events(Gdk.ModifierType.BUTTON1_MASK)
self._player_frame = builder.get_object("player_frame")
@@ -395,9 +402,14 @@ class Application(Gtk.Application):
""" Processing command line parameters. """
options = command_line.get_options_dict()
options = options.end().unpack()
if "log" in options:
init_logger()
if "record" in options:
log("Starting record of current stream...")
log("Not implemented yet!")
self.activate()
return 0
@@ -474,9 +486,15 @@ class Application(Gtk.Application):
""" Function for force ctrl press event for view """
event.state |= MOD_MASK
@run_idle
def on_close_app(self, *args):
self.quit()
if self._recorder:
if self._recorder.is_record():
msg = "{}\n\n\t{}".format(get_message("Recording in progress!"), get_message("Are you sure?"))
if show_dialog(DialogType.QUESTION, self._main_window, msg) == Gtk.ResponseType.CANCEL:
return True
self._recorder.release()
GLib.idle_add(self.quit)
def on_resize(self, window):
""" Stores new size properties for app window after resize """
@@ -925,7 +943,7 @@ class Application(Gtk.Application):
""" Shows satellites editor dialog """
show_satellites_dialog(self._main_window, self._settings)
def on_download(self, action, value):
def on_download(self, action=None, value=None):
DownloadDialog(transient=self._main_window,
settings=self._settings,
open_data_callback=self.open_data,
@@ -1843,6 +1861,41 @@ class Application(Gtk.Application):
self._player_tool_bar.set_visible(visible)
self._status_bar_box.set_visible(visible and not self._app_info_box.get_visible())
# ************************* Record ***************************** #
def on_record(self, button):
if show_dialog(DialogType.QUESTION, self._main_window) == Gtk.ResponseType.CANCEL:
return True
if not self._recorder:
try:
self._recorder = Recorder.get_instance()
except (ImportError, NameError, AttributeError):
self.show_error_dialog("No VLC is found. Check that it is installed!")
return
is_record = self._recorder.is_record()
if is_record:
self._recorder.stop()
else:
self._http_api.send(HttpRequestType.STREAM_CURRENT, None, self.record)
def record(self, m3u):
if m3u:
url = [s for s in m3u.split("\n") if not s.startswith("#")]
if url:
self._recorder.record(url[0], self._settings.records_path, self._service_name_label.get_text())
GLib.timeout_add_seconds(1, self.update_record_button, priority=GLib.PRIORITY_LOW)
def update_record_button(self):
is_rec = self._recorder.is_record()
if not is_rec:
self._record_image.set_visible(True)
else:
self._record_image.set_visible(not self._record_image.get_visible())
return is_rec
# ************************ HTTP API **************************** #
def init_http_api(self):

View File

@@ -1343,6 +1343,7 @@ Author: Dmitriy Yefremov
</child>
<child>
<object class="GtkPaned" id="main_data_paned">
<property name="width_request">320</property>
<property name="height_request">250</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
@@ -2525,7 +2526,28 @@ Author: Dmitriy Yefremov
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="record_button">
<property name="name">status-bar-button</property>
<property name="can_focus">False</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Record</property>
<signal name="clicked" handler="on_record" swapped="no"/>
<child>
<object class="GtkImage" id="record_button_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-media-record</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
@@ -2551,7 +2573,7 @@ Author: Dmitriy Yefremov
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="position">3</property>
</packing>
</child>
<child>
@@ -2570,7 +2592,7 @@ Author: Dmitriy Yefremov
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
<property name="position">4</property>
</packing>
</child>
<child>
@@ -2584,7 +2606,7 @@ Author: Dmitriy Yefremov
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
<property name="position">5</property>
</packing>
</child>
</object>