# This file is part of Gajim. # # Gajim is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published # by the Free Software Foundation; version 3 only. # # Gajim is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Gajim. If not, see . import logging from gi.repository import GLib from gajim.common import app from gajim.common.i18n import _ from . import gstreamer from .util import get_builder try: from gi.repository import Gst # pylint: disable=ungrouped-imports except Exception: pass log = logging.getLogger('gajim.gui.preview') class VideoPreview: def __init__(self): self._ui = get_builder('video_preview.ui') self._active = False self._av_pipeline = None self._av_src = None self._av_sink = None self._av_widget = None @property def widget(self): return self._ui.video_preview_box @property def is_active(self): return self._active def toggle_preview(self, value): self._active = value if value: return self._enable_preview() return self._disable_preview() def _enable_preview(self): src_name = app.settings.get('video_input_device') try: self._av_src = Gst.parse_bin_from_description(src_name, True) except GLib.Error as error: log.error(error) log.error('Failed to parse "%s" as Gstreamer element', src_name) self._set_error_text() return sink, widget, name = gstreamer.create_gtk_widget() if sink is None: log.error('Failed to obtain a working Gstreamer GTK+ sink, ' 'video support will be disabled') self._set_error_text() return self._set_sink_text(name) if self._av_pipeline is None: self._av_pipeline = Gst.Pipeline.new('preferences-pipeline') else: self._av_pipeline.set_state(Gst.State.NULL) self._av_pipeline.add(sink) self._av_sink = sink if self._av_widget is not None: self._ui.video_preview_box.remove(self._av_widget) self._ui.video_preview_placeholder.set_visible(False) self._ui.video_preview_box.pack_end(widget, True, True, 0) self._av_widget = widget self._av_pipeline.add(self._av_src) self._av_src.link(self._av_sink) self._av_pipeline.set_state(Gst.State.PLAYING) def _disable_preview(self): if self._av_pipeline is not None: self._av_pipeline.set_state(Gst.State.NULL) if self._av_src is not None: self._av_pipeline.remove(self._av_src) if self._av_sink is not None: self._av_pipeline.remove(self._av_sink) self._av_src = None self._av_sink = None if self._av_widget is not None: self._ui.video_preview_box.remove(self._av_widget) self._ui.video_preview_placeholder.set_visible(True) self._av_widget = None self._av_pipeline = None def _set_sink_text(self, sink_name): text = '' if sink_name == 'gtkglsink': text = _('' 'OpenGL accelerated') elif sink_name == 'gtksink': text = _('' 'Not accelerated') self._ui.video_source_label.set_markup(text) def _set_error_text(self): self._ui.video_source_label.set_text( _('Something went wrong. Video feature disabled.')) def refresh(self): self.toggle_preview(False) self.toggle_preview(True)