def search (self, key, last_time, store, callback, *args): location = key.get_info("location") if location is None: print("not searching, we don't have a location") callback(args) return if location.startswith("file://") is False: print("not searching in non-local file %s" % location) callback(args) return # should avoid checking the playing entry, since the player already handles that self.callback = callback self.callback_args = args self.store = store self.search_key = key print("discovering %s" % location) self.discoverer = GstPbutils.Discoverer(timeout=Gst.SECOND*5) self.discoverer.connect('finished', self.finished_cb) self.discoverer.connect('discovered', self.discovered_cb) self.discoverer.start() self.discoverer.discover_uri_async(location)
def set_uri(self, uri): """Set the URI of the file to play.""" self.ready = False self._playbin.props.uri = uri # XXX: On Windows, we'd need HWND instead of XID, # but there seems to be no clear way to do this. # http://stackoverflow.com/q/23021327/653825 self._xid = self.widget.get_window().get_xid() self.subtitle_text = "" try: # Find out the exact framerate to be able # to convert between position types. from gi.repository import GstPbutils discoverer = GstPbutils.Discoverer() self._info = discoverer.discover_uri(uri) stream = self._info.get_video_streams()[0] num = float(stream.get_framerate_num()) denom = float(stream.get_framerate_denom()) self.calc = aeidon.Calculator(num / denom) self.ready = True except Exception as error: title = _("Failed to initialize playback") dialog = gaupol.ErrorDialog(None, title, str(error)) dialog.add_button(_("_OK"), Gtk.ResponseType.OK) dialog.set_default_response(Gtk.ResponseType.OK) gaupol.util.flash_dialog(dialog)
def set_uri(self, uri): """Set the URI of the file to play.""" self.ready = False self._playbin.props.uri = uri self.subtitle_text = "" try: # Find out the exact framerate to be able # to convert between position types. from gi.repository import GstPbutils discoverer = GstPbutils.Discoverer() self._info = discoverer.discover_uri(uri) streams = self._info.get_stream_list() stream_types = [x.get_stream_type_nick() for x in streams] if "video" not in stream_types: raise Exception(_("No video streams found")) stream = self._info.get_video_streams()[0] num = float(stream.get_framerate_num()) denom = float(stream.get_framerate_denom()) self.calc = aeidon.Calculator(num/denom) self.ready = True except Exception as error: title = _("Failed to initialize playback") dialog = gaupol.ErrorDialog(None, title, str(error)) dialog.add_button(_("_OK"), Gtk.ResponseType.OK) dialog.set_default_response(Gtk.ResponseType.OK) gaupol.util.flash_dialog(dialog) else: # Make stream tags available from _playbin self._playbin.set_state(Gst.State.PAUSED) self._playbin.get_state(Gst.CLOCK_TIME_NONE)
def __init__(self): GObject.GObject.__init__(self) self.playlist = None self.playlistType = None self.playlistId = None self.playlistField = None self.currentTrack = None self._lastState = Gst.State.PAUSED self.cache = AlbumArtCache.get_default() self._symbolicIcon = self.cache.make_default_icon(ART_SIZE, ART_SIZE) Gst.init(None) self.discoverer = GstPbutils.Discoverer() self.discoverer.connect('discovered', self._on_discovered) self.discoverer.start() self._discovering_urls = {} self.player = Gst.ElementFactory.make('playbin', 'player') self.bus = self.player.get_bus() self.bus.add_signal_watch() self._settings = Gio.Settings.new('org.gnome.Music') self._settings.connect('changed::repeat', self._on_settings_changed) self.repeat = self._settings.get_enum('repeat') self.bus.connect('message::state-changed', self._on_bus_state_changed) self.bus.connect('message::error', self._onBusError) self.bus.connect('message::eos', self._on_bus_eos) self._setup_view() self.playlist_insert_handler = 0 self.playlist_delete_handler = 0
def get_video_info(filename): uri = pathlib.Path(filename).absolute().as_uri() discoverer = GstPbutils.Discoverer() info = discoverer.discover_uri(uri) streams = info.get_video_streams() assert len(streams) == 1 return streams[0]
def __init__(self, arg, uri=os.path.dirname(os.path.abspath(__file__))): self.arg = arg self.uri = uri stream = GstPbutils.Discoverer() path_1 = f'file://{self.arg}' path_2 = f'file://{uri}{self.arg}' try: self._info = stream.discover_uri(path_1) except GLib.Error: self._info = stream.discover_uri(path_2)
def search_tags(self): """ Initiate fetching meta tags. Result will be handled in search_tags_result """ location = self.entry.get_playback_uri() self.discoverer = GstPbutils.Discoverer(timeout=Gst.SECOND * 3) self.discoverer.connect('discovered', self.search_tags_result) self.discoverer.start() self.discoverer.discover_uri_async(location)
def gst_discover_duration(pathname): # use gstreamer to find get_duration print("gst_discover_duration") discoverer = GstPbutils.Discoverer() # try: d = discoverer.discover_uri('file://{}'.format(pathname)) seconds = d.get_duration() / float(Gst.SECOND) #except : # seconds=None return seconds
def get_gstreamer_length(path): uri = "file://" + path try: discoverer = GstPbutils.Discoverer() info: DiscovererInfo = discoverer.discover_uri(uri) duration = info.get_duration() except Exception as e: pass if duration and duration > 0: return True, int(duration / 1000000000) else: return False, None
def __init__(self, parent_window): GObject.GObject.__init__(self) self._parent_window = parent_window self.playlist = None self.playlistType = None self.playlistId = None self.playlistField = None self.currentTrack = None self.currentTrackUri = None self._lastState = Gst.State.PAUSED self.cache = AlbumArtCache.get_default() self._noArtworkIcon = self.cache.get_default_icon(ART_SIZE, ART_SIZE) self._loadingIcon = self.cache.get_default_icon( ART_SIZE, ART_SIZE, True) self._missingPluginMessages = [] Gst.init(None) GstPbutils.pb_utils_init() self.discoverer = GstPbutils.Discoverer() self.discoverer.connect('discovered', self._on_discovered) self.discoverer.start() self._discovering_urls = {} self.player = Gst.ElementFactory.make('playbin', 'player') self.bus = self.player.get_bus() self.bus.add_signal_watch() self.setup_replaygain() self._settings = Gio.Settings.new('org.gnome.Music') self._settings.connect('changed::repeat', self._on_repeat_setting_changed) self._settings.connect('changed::replaygain', self._on_replaygain_setting_changed) self.repeat = self._settings.get_enum('repeat') self.replaygain = self._settings.get_value('replaygain') is not None self.toggle_replaygain(self.replaygain) self.bus.connect('message::state-changed', self._on_bus_state_changed) self.bus.connect('message::error', self._onBusError) self.bus.connect('message::element', self._on_bus_element) self.bus.connect('message::eos', self._on_bus_eos) self._setup_view() self.playlist_insert_handler = 0 self.playlist_delete_handler = 0 self._check_last_fm()
def uri(self, uri): if uri == self.uri: return self._playbin.set_state(Gst.State.NULL) self._duration = Gst.CLOCK_TIME_NONE self._playbin.set_property('uri', uri) self._playbin.set_state(Gst.State.PAUSED) if self._duration == Gst.CLOCK_TIME_NONE: discoverer = GstPbutils.Discoverer() info = discoverer.discover_uri(uri) if info: self._set_duration(info.get_duration()) else: print("Failed to discover media info")
def __init__(self, parent_window): super().__init__() self._parent_window = parent_window self.playlist = None self.playlistType = None self.playlistId = None self.playlistField = None self.currentTrack = None self.currentTrackUri = None scale = parent_window.get_scale_factor() self.cache = AlbumArtCache(scale) self._loading_icon_surface = DefaultIcon(scale).get( DefaultIcon.Type.loading, ArtSize.XSMALL) self._missingPluginMessages = [] Gst.init(None) GstPbutils.pb_utils_init() self.discoverer = GstPbutils.Discoverer() self.discoverer.connect('discovered', self._on_discovered) self.discoverer.start() self._discovering_urls = {} self.player = Gst.ElementFactory.make('playbin', 'player') self.bus = self.player.get_bus() self.bus.add_signal_watch() self.setup_replaygain() self._settings = Gio.Settings.new('org.gnome.Music') self._settings.connect('changed::repeat', self._on_repeat_setting_changed) self._settings.connect('changed::replaygain', self._on_replaygain_setting_changed) self.repeat = self._settings.get_enum('repeat') self.replaygain = self._settings.get_value('replaygain') is not None self.toggle_replaygain(self.replaygain) self.bus.connect('message::state-changed', self._on_bus_state_changed) self.bus.connect('message::error', self._onBusError) self.bus.connect('message::element', self._on_bus_element) self.bus.connect('message::eos', self._on_bus_eos) self._setup_view() self.playlist_insert_handler = 0 self.playlist_delete_handler = 0 self._lastfm = LastFmScrobbler()
def __init__(self): super().__init__() GstPbutils.pb_utils_init() self._songs = [] self._shuffle_indexes = [] self._current_index = 0 self._type = -1 self._id = -1 self._validation_indexes = None self._discoverer = GstPbutils.Discoverer() self._discoverer.connect('discovered', self._on_discovered) self._discoverer.start() self.connect("notify::repeat-mode", self._on_repeat_mode_changed)
def __init__(self): super().__init__() self._songs = [] self._shuffle_indexes = [] self._current_index = 0 self._type = -1 self._id = -1 self._settings = Gio.Settings.new('org.gnome.Music') self._settings.connect('changed::repeat', self._on_repeat_setting_changed) self._repeat = self._settings.get_enum('repeat') self._validation_indexes = None self._discoverer = GstPbutils.Discoverer() self._discoverer.connect('discovered', self._on_discovered) self._discoverer.start()
def __init__(self, application): super().__init__() GstPbutils.pb_utils_init() self._app = application self._log = application.props.log self._position = 0 self._validation_songs = {} self._discoverer = GstPbutils.Discoverer() self._discoverer.connect("discovered", self._on_discovered) self._discoverer.start() self._coremodel = self._app.props.coremodel self._model = self._coremodel.props.playlist_sort self._model_recent = self._coremodel.props.recent_playlist self.connect("notify::repeat-mode", self._on_repeat_mode_changed)
def gst_discover(pathname): # get start time using gstreamer to read the media file header discoverer = GstPbutils.Discoverer() d = discoverer.discover_uri('file://{}'.format(pathname)) # seconds = d.get_duration() / float(Gst.SECOND) tags = d.get_tags() dt = tags.get_date_time("datetime")[1] print(dt.to_iso8601_string()) start = datetime.datetime( year=dt.get_year(), month=dt.get_month(), day=dt.get_day(), hour=dt.get_hour(), minute=dt.get_minute(), second=dt.get_second(), ) return start
def get_video_info(self): """Return information about the current video. """ uri = self.get_uri() if not Gst.uri_is_valid(uri): # Let's try to interpret it as a filename uri = Gst.filename_to_uri(uri) d = GstPbutils.Discoverer() try: info = d.discover_uri(uri) except Exception as e: logger.error("Cannot find video info: %s", e.message) info = None default = { 'uri': uri, 'framerate_denom': 1, 'framerate_num': config.data.preferences['default-fps'], 'width': 640, 'height': 480, 'duration': 0, } if info is None: # Return default data. logger.warning( "Could not find information about video, using absurd defaults." ) return default if not info.get_video_streams(): # Could be an audio file. default['duration'] = info.get_duration() / Gst.MSECOND return default stream = info.get_video_streams()[0] return { 'uri': uri, 'framerate_denom': stream.get_framerate_denom(), 'framerate_num': stream.get_framerate_num(), 'width': stream.get_width(), 'height': stream.get_height(), 'duration': info.get_duration() / Gst.MSECOND, }
def gst_discover_start(pathname): # get start time using gstreamer to read the media file header print("gst_discover_start") discoverer = GstPbutils.Discoverer() d = discoverer.discover_uri('file://{}'.format(pathname)) tags = d.get_tags() dt = tags.get_date_time("datetime")[1] # import code; code.interact(local=locals()) # print(dt.to_iso8601_string()) start = datetime.datetime( year=dt.get_year(), month=dt.get_month(), day=dt.get_day(), hour=dt.get_hour(), minute=dt.get_minute(), second=dt.get_second(), ) return start
def set_uri(self, uri): """ Set the URI of the file to play. You should have a window visible before calling `set_uri`. """ self._playbin.props.uri = uri self._xid = self.widget.props.window.get_xid() self.subtitle_text = "" try: # Find out the exact framerate to be able # to convert between position types. discoverer = GstPbutils.Discoverer() self._info = discoverer.discover_uri(uri) stream = self._info.get_video_streams()[0] num = float(stream.get_framerate_num()) denom = float(stream.get_framerate_denom()) self.calc = aeidon.Calculator(num / denom) except Exception: # If any of this fails, playback probably fails # as well and we'll show an error dialog then. pass
def set_uri(self, uri): """Set the URI of the file to play.""" self.ready = False self._playbin.props.uri = uri self.subtitle_text = "" try: # Find out the exact framerate to be able # to convert between position types. from gi.repository import GstPbutils discoverer = GstPbutils.Discoverer() self._info = discoverer.discover_uri(uri) stream = self._info.get_video_streams()[0] num = float(stream.get_framerate_num()) denom = float(stream.get_framerate_denom()) self.calc = aeidon.Calculator(num / denom) self.ready = True except Exception as error: title = _("Failed to initialize playback") dialog = gaupol.ErrorDialog(None, title, str(error)) dialog.add_button(_("_OK"), Gtk.ResponseType.OK) dialog.set_default_response(Gtk.ResponseType.OK) gaupol.util.flash_dialog(dialog)
def __init__(self, parent_window): super().__init__() self._parent_window = parent_window self.playlist = None self.playlist_type = None self.playlist_id = None self.playlist_field = None self.current_song = None self._next_song = None self._shuffle_history = deque(maxlen=10) self._new_clock = True Gst.init(None) GstPbutils.pb_utils_init() self._discoverer = GstPbutils.Discoverer() self._discoverer.connect('discovered', self._on_discovered) self._discoverer.start() self._discovering_urls = {} self._settings = Gio.Settings.new('org.gnome.Music') self._settings.connect( 'changed::repeat', self._on_repeat_setting_changed) self.repeat = self._settings.get_enum('repeat') self.playlist_insert_handler = 0 self.playlist_delete_handler = 0 self._player = GstPlayer() self._player.connect('clock-tick', self._on_clock_tick) self._player.connect('eos', self._on_eos) root_window = parent_window.get_toplevel() self._inhibit_suspend = InhibitSuspend(root_window, self) self._lastfm = LastFmScrobbler()
def run(self): self.next_purge_check = time.time() if obplayer.Config.setting( 'alerts_purge_files') else None self.next_expired_check = time.time() + 30 self.next_alert_check = time.time() while not self.thread.stopflag.wait(1): try: present_time = time.time() # process alerts waiting in the dispatch queue if len(self.alert_queue) > 0: alert = None with self.lock: alert = self.alert_queue.pop() with self.dispatch_lock: self.handle_dispatch(alert) # deactivate alerts that have expired if present_time > self.next_expired_check: self.next_expired_check = present_time + 30 expired_list = [] with self.lock: for alert in self.alerts_active.values(): if alert.is_expired(): obplayer.Log.log( "alert %s has expired" % (obplayer.alerts.ObAlert.reference( alert.sent, alert.identifier), ), 'alerts') expired_list.append(alert) for alert in expired_list: self.mark_expired(alert) # delete old alert data if self.next_purge_check is not None and present_time > self.next_purge_check: self.next_purge_check = present_time + 86400 basedir = obplayer.ObData.get_datadir() + "/alerts" then = datetime.datetime.now() - datetime.timedelta( days=90) for filename in os.listdir(basedir): try: (year, month, day) = filename[:10].split('_') filedate = datetime.datetime( int(year), int(month), int(day)) if filedate < then: obplayer.Log.log( "deleting alert file " + filename, 'debug') os.remove(os.path.join(basedir, filename)) except: pass # play active alerts if present_time > self.next_alert_check: if len(self.alerts_active) > 0: obplayer.Log.log( "playing active alerts (%d alert(s) to play)" % (len(self.alerts_active), ), 'alerts') self.ctrl.hold_requests(True) self.ctrl.add_request( media_type='break', title="alert lead in delay", duration=self.leadin_delay, onstart=self.trigger_alert_cycle_start) expired_list = [] with self.lock: self.trigger_alert_cycle_init() for alert in self.sort_by_importance( self.alerts_active.values()): #alert_media = alert.get_media_info(self.language_primary, self.voice_primary, self.language_secondary, self.voice_secondary) if obplayer.Config.setting( 'alerts_broadcast_message_in_first_nations_languages' ): alert_media = alert.get_media_info( self.language_primary, self.voice_primary, self.language_secondary, self.voice_secondary, True) else: alert_media = alert.get_media_info( self.language_primary, self.voice_primary, self.language_secondary, self.voice_secondary) print(alert_media) #time.sleep(20) #alert.times_played += 1 start_time = self.ctrl.get_requests_endtime() if alert.times_played <= 1: alert.times_played += 1 if os.path.isfile( obplayer.Config.setting( 'alerts_alert_start_audio') ) and obplayer.Config.setting( 'alerts_play_leadin_enable' ) == True: d = GstPbutils.Discoverer() mediainfo = d.discover_uri( obplayer.Player.file_uri( obplayer.Config.setting( 'alerts_alert_start_audio') )) #print('leadin message duration ' + str(mediainfo.get_duration() / float(Gst.SECOND))) if mediainfo.get_duration() / float( Gst.SECOND) > 10.0: obplayer.Log.log( 'alert start message is longer then 10 seconds! max allowed is 10 seconds. only playing the first 10 seconds.', 'alerts') self.ctrl.add_request( media_type='audio', uri=obplayer.Player.file_uri( obplayer.Config.setting( 'alerts_alert_start_audio' )), duration=10, artist=mediainfo['audio'] ['artist'], title='ledin message', overlay_text=mediainfo['audio'] ['overlay_text']) else: self.ctrl.add_request( media_type='audio', uri=obplayer.Player.file_uri( obplayer.Config.setting( 'alerts_alert_start_audio' )), duration=mediainfo. get_duration() / float(Gst.SECOND), artist=mediainfo['audio'] ['artist'], title='ledin message', overlay_text=mediainfo['audio'] ['overlay_text']) self.ctrl.add_request( media_type='break', title="alert tone delay", duration=1.0) # Play US/EAS attn tone if obplayer.Config.setting( 'alerts_location_type') == 'US': self.ctrl.add_request( media_type='audio', uri=obplayer.Player.file_uri( "obplayer/alerts/data", "attention-signal.ogg"), duration=8, artist=alert_media[0]['audio'] ['artist'], title=alert_media[0]['audio'] ['title'], overlay_text=alert_media[0] ['audio']['overlay_text']) # Play CA/Alert Ready attn tone else: self.ctrl.add_request( media_type='audio', uri=obplayer.Player.file_uri( "obplayer/alerts/data", "canadian-attention-signal.mp3" ), duration=8, artist=alert_media[0]['audio'] ['artist'], title=alert_media[0]['audio'] ['title'], overlay_text=alert_media[0] ['audio']['overlay_text']) for mediainfo in alert_media: self.ctrl.add_request( **mediainfo['audio']) if 'visual' in mediainfo: self.ctrl.add_request( start_time=start_time, **mediainfo['visual']) # if alert_media['secondary']: # start_time = self.ctrl.get_requests_endtime() # self.ctrl.add_request(**alert_media['secondary']['audio']) # if 'visual' in alert_media['secondary']: # self.ctrl.add_request(start_time=start_time, **alert_media['secondary']['visual']) # # if alert_media['first_nation']: # start_time = self.ctrl.get_requests_endtime() # self.ctrl.add_request(**alert_media['first_nation']['audio']) # if 'visual' in alert_media['first_nation']: # self.ctrl.add_request(start_time=start_time, **alert_media['first_nation']['visual']) self.trigger_alert_cycle_each( alert, alert_media, self) if (self.repeat_times > 0 and alert.times_played >= self.repeat_times) or ( alert.max_plays > 0 and alert.times_played >= alert.max_plays): expired_list.append(alert) self.ctrl.add_request( media_type='break', title="alert lead out delay", duration=self.leadout_delay, onend=self.trigger_alert_cycle_stop) self.ctrl.adjust_request_times(time.time()) self.ctrl.hold_requests(False) for alert in expired_list: self.mark_expired(alert) self.next_alert_check = self.ctrl.get_requests_endtime( ) + (self.repeat_interval * 60) """ print("Starting") for req in self.ctrl.queue: print("{start_time} {end_time} {media_type}".format(**req)) print("Ending") """ # reset fetcher if we stop receiving heartbeats # check for us location settings. US CAP server don't return heartbeats in must case # and never in the same format as alert ready does. if obplayer.Config.setting('alerts_location_type') == 'CA': if self.fetcher.last_received and time.time( ) - self.fetcher.last_received > 360: obplayer.Log.log( "no heartbeat received for 6 min. resetting alert fetcher", 'error') self.fetcher_timeouts = +1 # Play beep after no heartbeats for 6 minutes. if self.fetcher_timeouts > 10: os.system( "play -q -n synth 0.8 sin 880; sleep 1; play -q -n synth 0.8 sin 880; sleep 1; play -q -n synth 0.8 sin 880; sleep 1; play -q -n synth 0.8 sin 880" ) # resetting timeouts count. obplayer.Log.log( "no heartbeat received timedout. alerting user!", 'error') self.fetcher_timeouts = 0 self.fetcher.close() except: obplayer.Log.log( "exception in " + self.thread.name + " thread", 'error') obplayer.Log.log(traceback.format_exc(), 'error')
def __init__(self): self.media = [] self.media_types = [] self.image_types = [] self.media_types.append('audio/x-flac') self.media_types.append('audio/flac') self.media_types.append('audio/mpeg') self.media_types.append('audio/ogg') # TODO we're always headless new so we never play images or video?? #if obplayer.Config.headless == False: self.image_types.append('image/jpeg') self.image_types.append('image/png') self.image_types.append('image/svg+xml') self.media_types.append('application/ogg') self.media_types.append('video/ogg') self.media_types.append('video/x-msvideo') self.media_types.append('video/mp4') self.media_types.append('video/mpeg') self.play_index = 0 self.image_duration = 15.0 m = magic.open(magic.MAGIC_MIME) m.load() for (dirname, dirnames, filenames) in os.walk( unicode(obplayer.Config.setting('fallback_media'))): for filename in filenames: try: path = os.path.join(dirname, filename) uri = obplayer.Player.file_uri(path) filetype = m.file(path.encode('utf-8')).split(';')[0] if filetype in self.media_types: d = GstPbutils.Discoverer() mediainfo = d.discover_uri(uri) media_type = None for stream in mediainfo.get_video_streams(): if stream.is_image(): media_type = 'image' else: media_type = 'video' break if not media_type and len( mediainfo.get_audio_streams()) > 0: media_type = 'audio' if media_type: # we discovered some more fallback media, add to our media list. self.media.append([ uri, filename, media_type, float(mediainfo.get_duration()) / Gst.SECOND ]) if filetype in self.image_types: self.media.append( [uri, filename, 'image', self.image_duration]) except: obplayer.Log.log( "exception while loading fallback media: " + dirname + '/' + filename, 'error') obplayer.Log.log(traceback.format_exc(), 'error') # shuffle the list random.shuffle(self.media) self.ctrl = obplayer.Player.create_controller('fallback', priority=25) self.ctrl.set_request_callback(self.do_player_request)
def generate_audio(self, language, voice=None): info = self.get_first_info(language, bestmatch=False) if info is None: self.media_info[language] = None return False truncate = not self.broadcast_immediately( ) and obplayer.Config.setting('alerts_truncate') message_text = info.get_message_text(truncate) # TODO there needs to be a better way to get the datadir location = obplayer.ObData.get_datadir() + "/alerts" if os.access(location, os.F_OK) == False: os.mkdir(location) filename = self.reference(self.sent, self.identifier) + "-" + language + ".wav" uri = obplayer.Player.file_uri(location, filename) resources = info.get_resources('audio') if resources: if resources[0].write_file(os.path.join(location, filename)) is False: return False elif message_text: self.write_tts_file(os.path.join(location, filename), message_text, voice) else: return False d = GstPbutils.Discoverer() mediainfo = d.discover_uri(uri) self.media_info[language] = {} self.media_info[language]['audio'] = { 'media_type': 'audio', 'artist': 'Emergency Alert', 'title': str(self.identifier), 'overlay_text': message_text, 'uri': uri, 'duration': (mediainfo.get_duration() / float(Gst.SECOND)) } # the NPAS Common Look and Feel guide states that audio content should not be more than 120 seconds if self.media_info[language]['audio']['duration'] > 120.0: self.media_info[language]['audio']['duration'] = 120.0 resources = info.get_resources('image') if resources: filename = self.reference( self.sent, self.identifier) + "-" + language + ".jpg" if resources[0].write_file(os.path.join(location, filename)) is False: return False self.media_info[language]['visual'] = { 'media_type': 'image', 'artist': 'Emergency Alert', 'title': str(self.identifier), #'overlay_text' : message_text, 'uri': obplayer.Player.file_uri(location, filename), 'duration': self.media_info[language]['audio']['duration'] } self.media_info[language]['audio']['overlay_text'] = None return True
def __init__(self, path: str): super().__init__() self.uri = pathlib.Path(path).as_uri() Gst.init(None) self.discoverer: GstPbutils.Discoverer = GstPbutils.Discoverer()
def generate_audio(self, language, voice=None, first_nation=False): print('TEST: {0}'.format(language)) # if language == 'eng': language = 'en-CA' # elif language == 'fr': language = 'fr-CA' #print('first_nation = {0}'.format(first_nation)) # if language == 'first_nation': # first_nation = True # else: # first_nation = False #print('Language: ' + str(self.lang_ref(language))) #info = self.get_first_info(self.lang_ref(language), bestmatch=False) info = self.get_first_info(language, bestmatch=False) #print(info.get_message_text(False)) #print(self.get_first_info('en-CA', bestmatch=False)) #time.sleep(20) if info is None: self.media_info[language] = None return False if first_nation == True: #print("First Nation Text: " + self.get_first_info('first_nation', bestmatch=True).get_message_text(False, True)) #message_text = self.get_first_info('first_nation', bestmatch=True).get_message_text(False, True) # over writting for cg scroll text and logging. TODO: shoud be first nation text here. cg_message_text = self.get_first_info( 'english', bestmatch=True).get_message_text(False) #print(cg_message_text) #time.sleep(20) #print("First Nation Text: " + message_text) #time.sleep(20) if first_nation == False: truncate = not self.broadcast_immediately( ) and obplayer.Config.setting('alerts_truncate') message_text = info.get_message_text(truncate) print(message_text) # print(message_text) # time.sleep(20) # TODO there needs to be a better way to get the datadir location = obplayer.ObData.get_datadir() + "/alerts" filename = self.reference(self.sent, self.identifier) + "-" + language + ".wav" uri = obplayer.Player.file_uri(location, filename) if os.access(location, os.F_OK) == False: os.mkdir(location) if first_nation == False: resources = info.get_resources('audio') if resources: if resources[0].write_file(os.path.join(location, filename)) is False: return False elif message_text: self.write_tts_file(os.path.join(location, filename), message_text, voice) else: return False else: #os.system('cp first_nations/{0}/{1} {3}'.format(language.lower(), event.lower(), os.path.join(location, filename))) #self.write_first_nations_file(os.path.join(location, filename), info.event.lower()) #print(self.get_first_info('first_nation', bestmatch=True).get_message_text(False, True)) self.write_first_nations_file( os.path.join(location, filename), self.get_first_info('first_nation', bestmatch=True).get_message_text( False, True)) # over writting for cg scroll text and logging. TODO: shoud be first nation text here. cg_message_text = self.get_first_info( 'english', bestmatch=True).get_message_text(False) uri = obplayer.Player.file_uri(location, filename) #print(uri) #time.sleep(20) d = GstPbutils.Discoverer() mediainfo = d.discover_uri(uri) self.media_info[language] = {} if first_nation: self.media_info[language]['audio'] = { 'media_type': 'audio', 'artist': 'Emergency Alert', 'title': str(self.identifier), 'overlay_text': 'A alert is in effect.', 'uri': uri, 'duration': (mediainfo.get_duration() / float(Gst.SECOND)) } else: self.media_info[language]['audio'] = { 'media_type': 'audio', 'artist': 'Emergency Alert', 'title': str(self.identifier), 'overlay_text': message_text, 'uri': uri, 'duration': (mediainfo.get_duration() / float(Gst.SECOND)) } # the NPAS Common Look and Feel guide states that audio content should not be more than 120 seconds if self.media_info[language]['audio']['duration'] > 120.0: self.media_info[language]['audio']['duration'] = 120.0 resources = info.get_resources('image') if resources: filename = self.reference( self.sent, self.identifier) + "-" + language + ".jpg" if resources[0].write_file(os.path.join(location, filename)) is False: return False self.media_info[language]['visual'] = { 'media_type': 'image', 'artist': 'Emergency Alert', 'title': str(self.identifier), #'overlay_text' : message_text, 'uri': obplayer.Player.file_uri(location, filename), 'duration': self.media_info[language]['audio']['duration'] } self.media_info[language]['audio']['overlay_text'] = None return True
import time from gi.repository import Gst from gi.repository import GstPbutils Gst.init() discoverer = GstPbutils.Discoverer() info = discoverer.discover_uri('file:///home/eric/Downloads/01.mp4') mysublist = info.get_subtitle_streams() print(len(mysublist)) i = 0 for x in mysublist: print(x.get_language(), i, info.get_subtitle_streams()[i].get_language()) i += 1 uri = 'file:///home/eric/Downloads/01.mp4' pipeline = Gst.ElementFactory.make("playbin", "playbin") pipeline.set_property('uri', uri) pipeline.set_state(Gst.State.PLAYING) time.sleep(2) subs = pipeline.get_property('n-text') print("there are ", subs, " Subtitles") auds = pipeline.get_property('n-audio') print("there are ", auds, " Audio streams") vids = pipeline.get_property('n-video') print("there are ", vids, " Video Streams")
def _get_discoverer_info(self, file_path): Gst.init() discoverer = GstPbutils.Discoverer() return discoverer.discover_uri("file://" + file_path)
def get_metadata(url): audio_url = get_audio_url(url) info = GstPbutils.Discoverer().discover_uri(audio_url) name = "" genres = "" web = "" tags = info.get_tags() n = tags.n_tags() for i in range(0, n): tag = tags.nth_tag_name(i) value = tags.get_string(tag)[1] print(i, ":", tag, "→", value) if tag == "organization": name = value elif tag == "genre": genres = value elif tag == "location": web = value stream_list = info.get_stream_list() audio_stream = stream_list[0] bitrate = str(int(audio_stream.get_bitrate() / 1000)) sample = str(audio_stream.get_sample_rate()) caps = audio_stream.get_caps() codec = GstPbutils.pb_utils_get_codec_description(caps) if bitrate == "0" or name == "" or genres == "" or web == "": try: req = urllib.request.urlopen(audio_url) head = req.info() req.close() except http.client.BadStatusLine: pass else: for tag in head.items(): match = re.match(r"ic[ey]-([a-z]+)", tag[0]) if match: print(match.group(1) + ": " + tag[1]) tagname = match.group(1) tagvalue = tag[1] if tagname == "br" or tagname == "bitrate": bitrate = tagvalue elif tagname == "name": name = tagvalue elif tagname == "genre": genres = tagvalue elif tagname == "url": web = tagvalue if bitrate == "0": bitrate = "N/A" if name == "": name = url dat = [name, url, genres, web, codec, bitrate, sample] return dat
def one_rf(self, dir, dv, offset_hours): """ get the start of this clip dv.filename generally looks like this: 2012-01-14/10:01:34.dv dir is generally ~/Videos/veyepar/client/show/dv/room parse the dir and filename strings. or use the filesystem_create generally use the parsed """ # 3 ways of getting the datetime this file started def fs_time(pathname): # get timestamp from filesystem st = os.stat(pathname) ts_start = datetime.datetime.fromtimestamp(st.st_mtime) return ts_start def parse_name(pathname): # parse string into datetime # remove extention filename = os.path.splitext(pathname)[0] # dvswitch appends -n in the event of filename colisions. # for start, dupe time is fine, so drop the -n for parsing if filename[-2] == '-': filename = filename[:-2] # for now, the last dir is the date, and the file is time: filename = '/'.join(filename.split('/')[-2:]) # swap : for _ (so either : or _ can be used in the filename) filename = filename.replace(':', '_') # parse start = datetime.datetime.strptime(filename, '%Y-%m-%d/%H_%M_%S') return start def frame_time(pathname): # get timestamp from first frame pass def gst_discover(pathname): # get start time using gstreamer to read the media file header discoverer = GstPbutils.Discoverer() d = discoverer.discover_uri('file://{}'.format(pathname)) # seconds = d.get_duration() / float(Gst.SECOND) tags = d.get_tags() dt = tags.get_date_time("datetime")[1] print(dt.to_iso8601_string()) start = datetime.datetime( year=dt.get_year(), month=dt.get_month(), day=dt.get_day(), hour=dt.get_hour(), minute=dt.get_minute(), second=dt.get_second(), ) return start def auto(pathname): # try to figure out what to use ext = os.path.splitext(pathname)[1] if ext == ".dv": start = parse_name(pathname) else: start = gst_discover(pathname) return start pathname = os.path.join(dir, dv.filename) print pathname print dv.filename # wacky python case statement # it's fun! start = { 'fn': parse_name, 'fs': fs_time, 'frame': frame_time, 'gst': gst_discover, 'auto': auto, }[self.options.time_source](pathname) # adjust for clock in wrong timezone # use both location and command line (the 2 get added) start += datetime.timedelta(hours=self.options.offset_hours) if offset_hours: start += datetime.timedelta(hours=offset_hours) # calc duration from size frames = dv.filesize / self.bpf dv_seconds = frames / self.fps # use gstreamer to find get_duration discoverer = GstPbutils.Discoverer() d = discoverer.discover_uri('file://{}'.format(pathname)) seconds = d.get_duration() / float(Gst.SECOND) print(dv_seconds, seconds) # assert(abs(dv_seconds-seconds)<max(dv_seconds/100.0,.1)) seconds = dv_seconds # store duration in fancy human readable format (bad idea) hms = seconds // 3600, (seconds % 3600) // 60, seconds % 60 duration = "%02d:%02d:%02d" % hms dv.start = start dv.duration = duration print "start:\t%s" % start # print "ts_start:\t%s" % ts_start # print "delta:\t%s" % (ts_start - start) print if not self.options.test: dv.save()