mirror of
https://github.com/DYefremov/DemonEditor.git
synced 2026-01-21 15:03:37 +01:00
added record of current service
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user