def __transcoderDoneCb(self, transcoder, asset): transcoder.disconnect_by_func(self.__transcoderDoneCb) transcoder.disconnect_by_func(self.__transcoderErrorCb) transcoder.disconnect_by_func(self.__proxyingPositionChangedCb) self.debug("Transcoder done with %s", asset.get_id()) self.__running_transcoders.remove(transcoder) proxy_uri = self.getProxyUri(asset) os.rename(Gst.uri_get_location(transcoder.props.dest_uri), Gst.uri_get_location(proxy_uri)) # Make sure that if it first failed loading, the proxy is forced to be # reloaded in the GES cache. GES.Asset.needs_reload(GES.UriClip, proxy_uri) GES.Asset.request_async(GES.UriClip, proxy_uri, None, self.__assetLoadedCb, asset, transcoder) try: self.__startTranscoder(self.__pending_transcoders.pop()) except IndexError: if not self.__running_transcoders: self._transcoded_durations = {} self._total_time_to_transcode = 0 self._start_proxying_time = 0
def __transcoderDoneCb(self, transcoder, asset): transcoder.disconnect_by_func(self.__transcoderDoneCb) transcoder.disconnect_by_func(self.__transcoderErrorCb) transcoder.disconnect_by_func(self.__proxyingPositionChangedCb) self.debug("Transcoder done with %s", asset.get_id()) self.__running_transcoders.remove(transcoder) proxy_uri = self.getProxyUri(asset) os.rename(Gst.uri_get_location(transcoder.props.dest_uri), Gst.uri_get_location(proxy_uri)) # Make sure that if it first failed loading, the proxy is forced to be # reloaded in the GES cache. GES.Asset.needs_reload(GES.UriClip, proxy_uri) GES.Asset.request_async(GES.UriClip, proxy_uri, None, self.__assetLoadedCb, asset, transcoder) try: self.__startTranscoder(self.__pending_transcoders.pop()) except IndexError: if not self.__running_transcoders: self._total_transcoded_time = 0 self._total_time_to_transcode = 0 self._start_proxying_time = 0
def test_mixed_proxies(self): sample_name = "30fps_numeroted_frames_red.mkv" with common.cloned_sample(sample_name): self.check_import([sample_name], proxying_strategy=ProxyingStrategy.NOTHING) asset = self.medialibrary.store[0].asset # Create and disable scaled proxy proxy = self.check_add_proxy(asset, scaled=True) scaled_uri = self.app.proxy_manager.get_proxy_uri(asset, scaled=True) self.check_disable_proxy(proxy, asset) # Create and disable HQ proxy proxy = self.check_add_proxy(asset) hq_uri = self.app.proxy_manager.get_proxy_uri(asset) self.check_disable_proxy(proxy, asset) # Check both files exist self.assertTrue(os.path.exists(Gst.uri_get_location(hq_uri))) self.assertTrue(os.path.exists(Gst.uri_get_location(scaled_uri))) # Enable and delete scaled proxy proxy = self.check_add_proxy(asset, scaled=True, check_progress=False) self.check_disable_proxy(proxy, asset, delete=True) # Check that only HQ Proxy exists self.assertFalse(os.path.exists(Gst.uri_get_location(scaled_uri))) self.assertTrue(os.path.exists(Gst.uri_get_location(hq_uri))) # Enable and delete HQ proxy proxy = self.check_add_proxy(asset, check_progress=False) self.check_disable_proxy(proxy, asset, delete=True)
def do_save_to_uri(self, timeline, uri, overwrite): if not Gst.uri_is_valid(uri) or Gst.uri_get_protocol(uri) != "file": Gst.error("Protocol not supported for file: %s" % uri) return False with tempfile.NamedTemporaryFile(suffix=".xges") as tmpxges: timeline.get_asset().save(timeline, "file://" + tmpxges.name, None, overwrite) linker = otio.media_linker.MediaLinkingPolicy.ForceDefaultLinker otio_timeline = otio.adapters.read_from_file(tmpxges.name, "xges", media_linker_name=linker) location = Gst.uri_get_location(uri) out_adapter = otio.adapters.from_filepath(location) otio.adapters.write_to_file(otio_timeline, Gst.uri_get_location(uri), out_adapter.name) return True
def __transcoder_done_cb(self, emitter, asset, transcoder): emitter.disconnect_by_func(self.__proxying_position_changed_cb) emitter.disconnect_by_func(self.__transcoder_done_cb) emitter.disconnect_by_func(self.__transcoder_error_cb) self.debug("Transcoder done with %s", asset.get_id()) self.__running_transcoders.remove(transcoder) proxy_uri = transcoder.props.dest_uri.rstrip(ProxyManager.part_suffix) os.rename(Gst.uri_get_location(transcoder.props.dest_uri), Gst.uri_get_location(proxy_uri)) shadow = self._is_shadow_transcoder(transcoder) second_transcoder = self._get_second_transcoder(transcoder) if second_transcoder and not shadow: # second_transcoder is the shadow for transcoder. # Defer loading until the shadow transcoder finishes. self.__waiting_transcoders.append([transcoder, asset]) else: # Make sure that if it first failed loading, the proxy is forced to # be reloaded in the GES cache. GES.Asset.needs_reload(GES.UriClip, proxy_uri) GES.Asset.request_async(GES.UriClip, proxy_uri, None, self.__asset_loaded_cb, asset, transcoder) if shadow: # Finish deferred loading for waiting scaled proxy transcoder. for pair in self.__waiting_transcoders: waiting_transcoder, waiting_asset = pair if waiting_transcoder.props.src_uri == transcoder.props.src_uri: proxy_uri = waiting_transcoder.props.dest_uri.rstrip( ProxyManager.part_suffix) GES.Asset.needs_reload(GES.UriClip, proxy_uri) GES.Asset.request_async(GES.UriClip, proxy_uri, None, self.__asset_loaded_cb, waiting_asset, waiting_transcoder) self.__waiting_transcoders.remove(pair) break try: self.__start_transcoder(self.__pending_transcoders.pop()) except IndexError: if not self.__running_transcoders: self._transcoded_durations = {} self._total_time_to_transcode = 0 self._start_proxying_time = 0
def test_delete_proxy(self): self.stop_using_proxies(delete_proxies=True) asset = self.medialibrary.storemodel[0][medialibrary.COL_ASSET] proxy_uri = self.app.proxy_manager.getProxyUri(asset) # Requesting UriClip sync will return None if the asset is not in cache # this way we make sure that this asset used to exist proxy = GES.Asset.request(GES.UriClip, proxy_uri) self.assertIsNotNone(proxy) self.assertFalse(os.path.exists(Gst.uri_get_location(proxy_uri))) self.assertIsNone(asset.get_proxy()) # And let's recreate the proxy file. self.app.project_manager.current_project.use_proxies_for_assets( [asset]) self.assertEqual(asset.creation_progress, 0) # Check that the info column notifies the user about progress self.assertTrue("Proxy creation progress:" in self.medialibrary. storemodel[0][medialibrary.COL_INFOTEXT]) # Run the mainloop and let _progressBarCb stop it when the proxy is # ready self.mainloop.run() self.assertEqual(asset.creation_progress, 100) self.assertEqual(asset.get_proxy(), proxy)
def _start_thumbnailing_cb(self): if not self.__start_id: # Can happen if stopGeneration is called because the clip has been # removed from the timeline after the PreviewGeneratorManager # started this job. return self.__start_id = None if isinstance(self.ges_elem, GES.ImageSource): self.debug("Generating thumbnail for image: %s", path_from_uri(self.uri)) self.__image_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( Gst.uri_get_location(self.uri), -1, self.thumb_height, True) self.thumb_width = self.__image_pixbuf.props.width self._update_thumbnails() self.emit("done") else: if not self.thumb_width: self.debug("Finding thumb width") self.pipeline = self._setup_pipeline() return # Update the thumbnails with what we already have, if anything. self._update_thumbnails() if self.queue: self.debug("Generating thumbnails for video: %s, %s", path_from_uri(self.uri), self.queue) # When the pipeline status is set to PAUSED, # the first thumbnail generation will be scheduled. self.pipeline = self._setup_pipeline() else: self.emit("done")
def testDeleteProxy(self): self.stopUsingProxies(True) asset = self.medialibrary.storemodel[0][medialibrary.COL_ASSET] proxy_uri = self.app.proxy_manager.getProxyUri(asset) # Requesting UriClip sync will return None if the asset is not in cache # this way we make sure that this asset used to exist proxy = GES.Asset.request(GES.UriClip, proxy_uri) self.assertIsNotNone(proxy) self.assertFalse(os.path.exists(Gst.uri_get_location(proxy_uri))) self.assertIsNone(asset.get_proxy()) # And let's recreate the proxy file. self.app.project_manager.current_project.useProxiesForAssets( [asset]) self.assertEqual(asset.creation_progress, 0) # Check that the info column notifies the user about progress self.assertTrue(_("Proxy creation progress: ") in self.medialibrary.storemodel[0][medialibrary.COL_INFOTEXT]) # Run the mainloop and let _progressBarCb stop it when the proxy is # ready self.mainloop.run() self.assertEqual(asset.creation_progress, 100) self.assertEqual(asset.get_proxy(), proxy)
def test_regenerate_scaled_proxy(self): sample_name = "30fps_numeroted_frames_red.mkv" with common.cloned_sample(sample_name): self.check_import([sample_name], proxying_strategy=ProxyingStrategy.NOTHING) asset = self.medialibrary.store[0].asset asset_uri = common.get_sample_uri(sample_name) # Create scaled proxy proxy = self.check_add_proxy(asset, scaled=True) proxy_uri = self.app.proxy_manager.get_proxy_uri(asset, scaled=True) # Change target resolution and trigger regeneration (1/4 Asset width) self.app.project_manager.current_project.scaled_proxy_width = 80 self.app.project_manager.current_project.scaled_proxy_height = 60 self.app.project_manager.current_project.regenerate_scaled_proxies( ) self.assertTrue("Proxy creation progress:" in self.medialibrary.store[0].infotext) self.mainloop.run() proxy = self.medialibrary.store[0].asset self.assertNotEqual(proxy.props.id, proxy_uri) stream = proxy.get_info().get_video_streams()[0] resolution = [stream.get_width(), stream.get_height()] self.assertEqual(resolution, [80, 60]) self.assertEqual(proxy.props.proxy_target.props.id, asset_uri) # Delete proxy self.check_disable_proxy(proxy, asset, delete=True) self.assertFalse(os.path.exists(Gst.uri_get_location(proxy_uri)))
def test_scaled_proxy_for_unsupported_asset(self): sample_name = "1sec_simpsons_trailer.mp4" with common.cloned_sample(sample_name): self.check_import([sample_name], proxying_strategy=ProxyingStrategy.AUTOMATIC) asset = self.medialibrary.store[0].asset # Mark all formats as unsupported with mock.patch.object(self.app.proxy_manager, "is_asset_format_well_supported", return_value=False): # Create scaled proxy proxy = self.check_add_proxy(asset, scaled=True, w=80, h=34) proxy_uri = self.app.proxy_manager.get_proxy_uri(asset, scaled=True) self.mainloop.run(until_empty=True) # Check that HQ proxy was created hq_uri = self.app.proxy_manager.get_proxy_uri(asset) self.assertTrue(os.path.exists(Gst.uri_get_location(hq_uri))) # Delete scaled proxy self.check_disable_proxy(proxy, asset, delete=True) self.mainloop.run() # Check that we revert to HQ proxy proxy = self.medialibrary.store[0].asset proxy_uri = self.app.proxy_manager.get_proxy_uri(asset, scaled=False) self.assertEqual(proxy.props.id, proxy_uri) # Delete HQ Proxy self.check_disable_proxy(proxy, asset, delete=True)
def _start_thumbnailing_cb(self): if not self.__start_id: # Can happen if stopGeneration is called because the clip has been # removed from the timeline after the PreviewGeneratorManager # started this job. return self.__start_id = None if isinstance(self.ges_elem, GES.ImageSource): self.debug('Now generating thumbnail for: %s', path_from_uri(self.uri)) self.__image_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( Gst.uri_get_location(self.uri), -1, self.thumb_height, True) self.thumb_width = self.__image_pixbuf.props.width self.emit("done") else: self.debug('Now generating thumbnails for: %s', path_from_uri(self.uri)) self.pipeline = self._setup_pipeline() self._schedule_next_thumb_generation() # Update the thumbnails with what we already have, if anything. self._update_thumbnails() # Stop calling me. return False
def test_delete_proxy(self): sample_name = "30fps_numeroted_frames_red.mkv" with common.cloned_sample(sample_name): self.stop_using_proxies(delete_proxies=True) asset = self.medialibrary.store[0].asset proxy_uri = self.app.proxy_manager.get_proxy_uri(asset) # Requesting UriClip sync will return None if the asset is not in cache # this way we make sure that this asset used to exist proxy = GES.Asset.request(GES.UriClip, proxy_uri) self.assertIsNotNone(proxy) self.assertFalse(os.path.exists(Gst.uri_get_location(proxy_uri))) self.assertIsNone(asset.get_proxy()) # And let's recreate the proxy file. self.app.project_manager.current_project.use_proxies_for_assets( [asset]) self.assertEqual(asset.creation_progress, 0) # Check that the info column notifies the user about progress self.assertTrue("Proxy creation progress:" in self.medialibrary.store[0].infotext) # Run the mainloop and let _progress_bar_cb stop it when the proxy is # ready self.mainloop.run() self.assertEqual(asset.creation_progress, 100) self.assertEqual(asset.get_proxy(), proxy)
def get_wavefile_location_for_uri(uri): """ Compute the URI where the pickled wave file should be stored """ filename = hash_file(Gst.uri_get_location(uri)) + ".wave" cache_dir = get_dir(os.path.join(xdg_cache_home(), "waves")) return os.path.join(cache_dir, filename)
def uri_is_valid(uri): """Checks if the specified URI is usable (of type file://). Will also check if the size is valid (> 0). Args: uri (str): The location to check. """ return (Gst.uri_is_valid(uri) and Gst.uri_get_protocol(uri) == "file" and len(os.path.basename(Gst.uri_get_location(uri))) > 0)
def uri_is_valid(uri): """Checks if the given uri is a valid uri (of type file://) Will also check if the size is valid (> 0). @param uri: The location to check @type uri: C{URI} """ return (Gst.uri_is_valid(uri) and Gst.uri_get_protocol(uri) == "file" and len(os.path.basename(Gst.uri_get_location(uri))) > 0)
def __init__(self, uri): Loggable.__init__(self) self._filehash = hash_file(Gst.uri_get_location(uri)) thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs")) self._dbfile = os.path.join(thumbs_cache_dir, self._filehash) self._db = sqlite3.connect(self._dbfile) self._cur = self._db.cursor() # Use this for normal db operations self._cur.execute("CREATE TABLE IF NOT EXISTS Thumbs\ (Time INTEGER NOT NULL PRIMARY KEY,\ Jpeg BLOB NOT NULL)")
def copy(self, uri): """Copies `self` to the specified `uri`. Args: uri (str): The place where to copy/save the ThumbnailCache """ filehash = hash_file(Gst.uri_get_location(uri)) thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs")) dbfile = os.path.join(thumbs_cache_dir, filehash) os.symlink(self._dbfile, dbfile)
def __init__(self, uri, size=100): object.__init__(self) self.hash = utils.misc.hash_file(Gst.uri_get_location(uri)) self.cache = {} self.queue = collections.deque() dbfile = os.path.join(settings.get_dir(os.path.join(settings.xdg_cache_home(), "thumbs")), self.hash) self.conn = sqlite3.connect(dbfile) self.cur = self.conn.cursor() self.cur.execute("CREATE TABLE IF NOT EXISTS Thumbs (Time INTEGER NOT NULL PRIMARY KEY,\ Data BLOB NOT NULL, Width INTEGER NOT NULL, Height INTEGER NOT NULL)") self.size = size
def _startLevelsDiscovery(self): self.log('Preparing waveforms for "%s"' % filename_from_uri(self._uri)) filename = hash_file(Gst.uri_get_location(self._uri)) + ".wave" cache_dir = get_dir(os.path.join(xdg_cache_home(), "waves")) filename = cache_dir + "/" + filename if os.path.exists(filename): self.samples = pickle.load(open(filename, "rb")) self._startRendering() else: self.wavefile = filename self._launchPipeline()
def check_disable_proxy(self, proxy, asset, delete=False): self.assertFalse(self.app.proxy_manager.is_proxy_asset(asset)) self.assertTrue(self.app.proxy_manager.is_proxy_asset(proxy)) self.app.project_manager.current_project.disable_proxies_for_assets( [proxy], delete_proxy_file=delete) self.assertIsNone(asset.get_proxy()) self.assertEqual(self.medialibrary.store[0].uri, asset.props.id) self.assertEqual(os.path.exists(Gst.uri_get_location(proxy.props.id)), not delete)
def __init__(self, uri): Loggable.__init__(self) # TODO: replace with utils.misc.hash_file self._filehash = hash_file(Gst.uri_get_location(uri)) self._filename = filename_from_uri(uri) # TODO: replace with pitivi.settings.xdg_cache_home() cache_dir = get_dir(os.path.join(xdg_dirs.xdg_cache_home, "pitivi"), autocreate) dbfile = os.path.join(get_dir(os.path.join(cache_dir, "thumbs")), self._filehash) self._db = sqlite3.connect(dbfile) self._cur = self._db.cursor() # Use this for normal db operations self._cur.execute("CREATE TABLE IF NOT EXISTS Thumbs\ (Time INTEGER NOT NULL PRIMARY KEY,\ Jpeg BLOB NOT NULL)")
def uri_is_reachable(uri): """ Check whether the given uri is reachable by GStreamer. @param uri: The location to check @type uri: C{str} @return: Whether the uri is reachable. """ if not uri_is_valid(uri): raise NotImplementedError( # Translators: "non local" means the project is not stored # on a local filesystem _("%s doesn't yet handle non-local projects") % APPNAME) return os.path.isfile(Gst.uri_get_location(uri))
def __init__(self, uri): Loggable.__init__(self) # TODO: replace with utils.misc.hash_file self._filehash = hash_file(Gst.uri_get_location(uri)) self._filename = os.path.basename(path_from_uri(uri)) # TODO: replace with pitivi.settings.xdg_cache_home() cache_dir = get_dir(os.path.join(xdg_dirs.xdg_cache_home, "pitivi"), autocreate) dbfile = os.path.join(get_dir(os.path.join(cache_dir, "thumbs")), self._filehash) self._db = sqlite3.connect(dbfile) self._cur = self._db.cursor() # Use this for normal db operations self._cur.execute("CREATE TABLE IF NOT EXISTS Thumbs\ (Time INTEGER NOT NULL PRIMARY KEY,\ Jpeg BLOB NOT NULL)")
def uri_is_reachable(uri): """Checks whether the specified URI is reachable by GStreamer. Args: uri (str): The location to check. Returns: bool: True when the URI is reachable, False otherwise. """ if not uri_is_valid(uri): raise NotImplementedError( # Translators: "non local" means the project is not stored # on a local filesystem _("%s doesn't yet handle non-local projects") % APPNAME) return os.path.isfile(Gst.uri_get_location(uri))
def do_can_load_uri(self, uri): try: if not Gst.uri_is_valid(uri) or Gst.uri_get_protocol(uri) != "file": return False except GLib.Error as e: Gst.error(str(e)) return False if uri.endswith(".xges"): return False try: return otio.adapters.from_filepath(Gst.uri_get_location(uri)) is not None except Exception as e: Gst.info("Could not load %s -> %s" % (uri, e)) return False
def __init__(self, uri): Loggable.__init__(self) self._filehash = hash_file(Gst.uri_get_location(uri)) thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs")) self._dbfile = os.path.join(thumbs_cache_dir, self._filehash) self._db = sqlite3.connect(self._dbfile) self._cur = self._db.cursor() self._cur.execute("CREATE TABLE IF NOT EXISTS Thumbs " "(Time INTEGER NOT NULL PRIMARY KEY, " " Jpeg BLOB NOT NULL)") # The cached (width, height) of the images. self._image_size = (0, 0) # The cached positions available in the database. self.positions = self.__existing_positions() # The ID of the autosave event. self.__autosave_id = None
def do_load_from_uri(self, timeline, uri): location = Gst.uri_get_location(uri) in_adapter = otio.adapters.from_filepath(location) assert(in_adapter) # can_load_uri should have ensured it is loadable linker = otio.media_linker.MediaLinkingPolicy.ForceDefaultLinker otio_timeline = otio.adapters.read_from_file( location, in_adapter.name, media_linker_name=linker ) with tempfile.NamedTemporaryFile(suffix=".xges") as tmpxges: otio.adapters.write_to_file(otio_timeline, tmpxges.name, "xges") formatter = GES.Formatter.get_default().extract() timeline.get_asset().add_formatter(formatter) return formatter.load_from_uri(timeline, "file://" + tmpxges.name)
def __init__(self, ges_elem, max_cpu_usage): Previewer.__init__(self, GES.TrackType.VIDEO, max_cpu_usage) Zoomable.__init__(self) Loggable.__init__(self) # Variables related to the timeline objects self.timeline = ges_elem.get_parent().get_timeline().ui self.ges_elem = ges_elem # Guard against malformed URIs self.uri = quote_uri(get_proxy_target(ges_elem).props.id) self.__preroll_timeout_id = 0 # Variables related to thumbnailing self.wishlist = [] self.queue = [] self._thumb_cb_id = None self._running = False # We should have one thumbnail per thumb_period. # TODO: get this from the user settings self.thumb_period = int(0.5 * Gst.SECOND) self.thumb_height = THUMB_HEIGHT self.__image_pixbuf = None if isinstance(ges_elem, GES.ImageSource): self.__image_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( Gst.uri_get_location(self.uri), -1, self.thumb_height, True) self.thumbs = {} self.thumb_cache = ThumbnailCache.get(self.uri) self._ensure_proxy_thumbnails_cache() self.thumb_width, unused_height = self.thumb_cache.getImagesSize() self.cpu_usage_tracker = CPUUsageTracker() self.interval = 500 # Every 0.5 second, reevaluate the situation # Connect signals and fire things up self.ges_elem.connect("notify::in-point", self._inpoint_changed_cb) self.pipeline = None self.gdkpixbufsink = None self.becomeControlled() self.connect("notify::height-request", self._height_changed_cb)
def test_rendering_with_unsupported_asset_scaled_proxies(self): """Tests rendering with scaled proxies.""" sample_name = "30fps_numeroted_frames_red.mkv" with common.cloned_sample(sample_name): self.check_import([sample_name], proxying_strategy=ProxyingStrategy.AUTOMATIC) project = self.app.project_manager.current_project proxy_manager = self.app.proxy_manager timeline_container = TimelineContainer( self.app, editor_state=self.app.gui.editor.editor_state) timeline_container.set_project(project) rendering_asset = None asset, = project.list_assets(GES.UriClip) with mock.patch.object(proxy_manager, "is_asset_format_well_supported", return_value=False): proxy = self.check_add_proxy(asset, scaled=True) # Check that HQ proxy was created hq_uri = self.app.proxy_manager.get_proxy_uri(asset) self.assertTrue(os.path.exists(Gst.uri_get_location(hq_uri)), hq_uri) layer, = project.ges_timeline.get_layers() clip = proxy.extract() layer.add_clip(clip) def _use_proxy_assets(): nonlocal layer, asset, rendering_asset clip, = layer.get_clips() rendering_asset = clip.get_asset() old_use_proxy_assets() dialog = self.create_rendering_dialog(project) old_use_proxy_assets = dialog._use_proxy_assets dialog._use_proxy_assets = _use_proxy_assets self.render(dialog) self.mainloop.run(until_empty=True) # Check rendering used HQ proxy self.assertTrue(proxy_manager.is_hq_proxy(rendering_asset)) # Check asset was replaced with scaled proxy after rendering self.assertTrue(proxy_manager.is_scaled_proxy( clip.get_asset()))
def _start_thumbnailing_cb(self): if not self.__start_id: # Can happen if stopGeneration is called because the clip has been # removed from the timeline after the PreviewGeneratorManager # started this job. return False self.__start_id = None self.debug("Generating thumbnail for image: %s", path_from_uri(self.uri)) self.__image_pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( Gst.uri_get_location(self.uri), -1, self.thumb_height, True) self.thumb_width = self.__image_pixbuf.props.width self._update_thumbnails() self.emit("done") # Stop calling me, I started already. return False
def _on_zoom_clicked_cb(self, button, increment): if self.current_preview_type == 'video': w, h = self.preview_video.get_size_request() if increment > 0: w *= 1.2 h *= 1.2 else: w *= 0.8 h *= 0.8 if (w, h) < self.original_dims: (w, h) = self.original_dims self.preview_video.set_size_request(int(w), int(h)) self.settings.FCpreviewWidth = int(w) self.settings.FCpreviewHeight = int(h) elif self.current_preview_type == 'image': pixbuf = self.preview_image.get_pixbuf() w = pixbuf.get_width() h = pixbuf.get_height() if increment > 0: w *= 1.2 h *= 1.2 else: w *= 0.8 h *= 0.8 if (w, h) < self.original_dims: (w, h) = self.original_dims pixbuf = GdkPixbuf.Pixbuf.new_from_file( Gst.uri_get_location(self.current_selected_uri)) pixbuf = pixbuf.scale_simple( int(w), int(h), GdkPixbuf.InterpType.BILINEAR) w = max(w, self.settings.FCpreviewWidth) h = max(h, self.settings.FCpreviewHeight) self.preview_image.set_size_request(int(w), int(h)) self.preview_image.set_from_pixbuf(pixbuf) self.preview_image.show() self.settings.FCpreviewWidth = int(w) self.settings.FCpreviewHeight = int(h)
def get_wavefile_location_for_uri(uri): filename = hash_file(Gst.uri_get_location(uri)) + ".wave" cache_dir = get_dir(os.path.join(xdg_cache_home(), "waves")) return os.path.join(cache_dir, filename)
def show_preview(self, uri, info): if info: self.preview_cache[uri] = info else: self.log("Show preview for " + uri) info = self.preview_cache.get(uri, None) if info is None: self.log("No preview for " + uri) return duration = info.get_duration() pretty_duration = beautify_length(duration) videos = info.get_video_streams() if videos: video = videos[0] if video.is_image(): self.current_preview_type = 'image' self.preview_video.hide() pixbuf = GdkPixbuf.Pixbuf.new_from_file(Gst.uri_get_location(uri)) pixbuf_w = pixbuf.get_width() pixbuf_h = pixbuf.get_height() w, h = self.__get_best_size(pixbuf_w, pixbuf_h) pixbuf = pixbuf.scale_simple(w, h, GdkPixbuf.InterpType.NEAREST) self.preview_image.set_from_pixbuf(pixbuf) self.preview_image.set_size_request(self.settings.FCpreviewWidth, self.settings.FCpreviewHeight) self.preview_image.show() self.bbox.show() self.play_button.hide() self.seeker.hide() self.b_zoom_in.show() self.b_zoom_out.show() else: self.current_preview_type = 'video' self.preview_image.hide() self.player.set_property("video-sink", self.__videosink) self.player.set_property("uri", self.current_selected_uri) self.player.set_state(Gst.State.PAUSED) self.pos_adj.props.upper = duration w, h = self.__get_best_size((video.get_par_num() / video.get_par_denom()) * video.get_width(), video.get_height()) self.preview_video.set_size_request(w, h) self.preview_video.show() self.bbox.show() self.play_button.show() self.seeker.show() self.b_zoom_in.show() self.b_zoom_out.show() self.description = _("<b>Resolution</b>: %d×%d") % \ ((video.get_par_num() / video.get_par_denom()) * video.get_width(), video.get_height()) +\ "\n" + _("<b>Duration</b>: %s") % pretty_duration + "\n" else: self.current_preview_type = 'audio' self.preview_video.hide() audio = info.get_audio_streams() if not audio: return audio = audio[0] self.pos_adj.props.upper = duration self.preview_image.set_from_file(DEFAULT_AUDIO_IMAGE) self.preview_image.show() self.preview_image.set_size_request(PREVIEW_WIDTH, PREVIEW_HEIGHT) self.description = beautify_stream(audio) + "\n" + \ _("<b>Duration</b>: %s") % pretty_duration + "\n" self.player.set_state(Gst.State.NULL) self.player.set_property("uri", self.current_selected_uri) self.player.set_property("video-sink", self.__fakesink) self.player.set_state(Gst.State.PAUSED) self.play_button.show() self.seeker.show() self.b_zoom_in.hide() self.b_zoom_out.hide() self.bbox.show()
def _show_preview(self, uri, info): self.log("Show preview for %s", uri) duration = info.get_duration() pretty_duration = beautify_length(duration) videos = info.get_video_streams() if videos: video = videos[0] if video.is_image(): self.current_preview_type = 'image' self.preview_video.hide() path = Gst.uri_get_location(uri) try: pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) except GLib.Error as error: self.debug("Failed loading image because: %s", error) self._show_error(error.message) return False pixbuf_w = pixbuf.get_width() pixbuf_h = pixbuf.get_height() w, h = self.__get_best_size(pixbuf_w, pixbuf_h) pixbuf = pixbuf.scale_simple(w, h, GdkPixbuf.InterpType.NEAREST) self.preview_image.set_from_pixbuf(pixbuf) self.preview_image.set_size_request( self.settings.FCpreviewWidth, self.settings.FCpreviewHeight) self.preview_image.show() self.bbox.show() self.play_button.hide() self.seeker.hide() self.b_zoom_in.show() self.b_zoom_out.show() else: self.current_preview_type = 'video' self.preview_image.hide() self.player.uri = self.current_selected_uri self.player.set_simple_state(Gst.State.PAUSED) self.pos_adj.props.upper = duration video_width = video.get_natural_width() video_height = video.get_natural_height() w, h = self.__get_best_size(video_width, video_height) self.preview_video.set_size_request(w, h) self.preview_video.props.ratio = video_width / video_height self.preview_video.show() self.bbox.show() self.play_button.show() self.seeker.show() self.b_zoom_in.show() self.b_zoom_out.show() self.description = "\n".join([ _("<b>Resolution</b>: %d×%d") % (video_width, video_height), _("<b>Duration</b>: %s") % pretty_duration ]) else: self.current_preview_type = 'audio' self.preview_video.hide() audio = info.get_audio_streams() if not audio: self.debug("Audio has no streams") return False audio = audio[0] self.pos_adj.props.upper = duration self.preview_image.set_from_icon_name("audio-x-generic", Gtk.IconSize.DIALOG) self.preview_image.show() self.preview_image.set_size_request(PREVIEW_WIDTH, PREVIEW_HEIGHT) self.description = "\n".join([ beautify_stream(audio), _("<b>Duration</b>: %s") % pretty_duration ]) self.player.set_simple_state(Gst.State.NULL) self.player.uri = self.current_selected_uri self.player.set_simple_state(Gst.State.PAUSED) self.play_button.show() self.seeker.show() self.b_zoom_in.hide() self.b_zoom_out.hide() self.bbox.show() return True
def show_preview(self, uri, info): if info: self.preview_cache[uri] = info else: self.log("Show preview for " + uri) info = self.preview_cache.get(uri, None) if info is None: self.log("No preview for " + uri) return duration = info.get_duration() pretty_duration = beautify_length(duration) videos = info.get_video_streams() if videos: video = videos[0] if video.is_image(): self.current_preview_type = 'image' self.preview_video.hide() pixbuf = GdkPixbuf.Pixbuf.new_from_file( Gst.uri_get_location(uri)) pixbuf_w = pixbuf.get_width() pixbuf_h = pixbuf.get_height() w, h = self.__get_best_size(pixbuf_w, pixbuf_h) pixbuf = pixbuf.scale_simple(w, h, GdkPixbuf.InterpType.NEAREST) self.preview_image.set_from_pixbuf(pixbuf) self.preview_image.set_size_request( self.settings.FCpreviewWidth, self.settings.FCpreviewHeight) self.preview_image.show() self.bbox.show() self.play_button.hide() self.seeker.hide() self.b_zoom_in.show() self.b_zoom_out.show() else: self.current_preview_type = 'video' self.preview_image.hide() self.player.set_property("video-sink", self.__videosink) self.player.set_property("uri", self.current_selected_uri) self.player.set_state(Gst.State.PAUSED) self.pos_adj.props.upper = duration w, h = self.__get_best_size( (video.get_par_num() / video.get_par_denom()) * video.get_width(), video.get_height()) self.preview_video.set_size_request(w, h) self.preview_video.show() self.bbox.show() self.play_button.show() self.seeker.show() self.b_zoom_in.show() self.b_zoom_out.show() self.description = _("<b>Resolution</b>: %d×%d") % \ ((video.get_par_num() / video.get_par_denom()) * video.get_width(), video.get_height()) +\ "\n" + _("<b>Duration</b>: %s") % pretty_duration + "\n" else: self.current_preview_type = 'audio' self.preview_video.hide() audio = info.get_audio_streams() if not audio: return audio = audio[0] self.pos_adj.props.upper = duration self.preview_image.set_from_file(DEFAULT_AUDIO_IMAGE) self.preview_image.show() self.preview_image.set_size_request(PREVIEW_WIDTH, PREVIEW_HEIGHT) self.description = beautify_stream(audio) + "\n" + \ _("<b>Duration</b>: %s") % pretty_duration + "\n" self.player.set_state(Gst.State.NULL) self.player.set_property("uri", self.current_selected_uri) self.player.set_property("video-sink", self.__fakesink) self.player.set_state(Gst.State.PAUSED) self.play_button.show() self.seeker.show() self.b_zoom_in.hide() self.b_zoom_out.hide() self.bbox.show()
def show_preview(self, uri, info): if info: self.preview_cache[uri] = info else: self.log("Show preview for " + uri) info = self.preview_cache.get(uri, None) if info is None: self.log("No preview for " + uri) return duration = info.get_duration() pretty_duration = beautify_length(duration) videos = info.get_video_streams() if videos: video = videos[0] if video.is_image(): self.current_preview_type = 'image' self.preview_video.hide() pixbuf = GdkPixbuf.Pixbuf.new_from_file( Gst.uri_get_location(uri)) pixbuf_w = pixbuf.get_width() pixbuf_h = pixbuf.get_height() w, h = self.__get_best_size(pixbuf_w, pixbuf_h) pixbuf = pixbuf.scale_simple( w, h, GdkPixbuf.InterpType.NEAREST) self.preview_image.set_from_pixbuf(pixbuf) self.preview_image.set_size_request( self.settings.FCpreviewWidth, self.settings.FCpreviewHeight) self.preview_image.show() self.bbox.show() self.play_button.hide() self.seeker.hide() self.b_zoom_in.show() self.b_zoom_out.show() else: self.current_preview_type = 'video' self.preview_image.hide() self.player.setClipUri(self.current_selected_uri) self.player.setState(Gst.State.PAUSED) self.pos_adj.props.upper = duration video_width = ( video.get_par_num() / video.get_par_denom()) * video.get_width() video_height = video.get_height() w, h = self.__get_best_size(video_width, video_height) self.preview_video.set_size_request(w, h) self.preview_video.setDisplayAspectRatio( float(video_width) / video_height) self.preview_video.show() self.bbox.show() self.play_button.show() self.seeker.show() self.b_zoom_in.show() self.b_zoom_out.show() self.description = "\n".join([ _("<b>Resolution</b>: %d×%d") % ( video_width, video_height), _("<b>Duration</b>: %s") % pretty_duration]) else: self.current_preview_type = 'audio' self.preview_video.hide() audio = info.get_audio_streams() if not audio: return audio = audio[0] self.pos_adj.props.upper = duration self.preview_image.set_from_icon_name( "audio-x-generic", Gtk.IconSize.DIALOG) self.preview_image.show() self.preview_image.set_size_request(PREVIEW_WIDTH, PREVIEW_HEIGHT) self.description = "\n".join([ beautify_stream(audio), _("<b>Duration</b>: %s") % pretty_duration]) self.player.setState(Gst.State.NULL) self.player.setClipUri(self.current_selected_uri) self.player.setState(Gst.State.PAUSED) self.play_button.show() self.seeker.show() self.b_zoom_in.hide() self.b_zoom_out.hide() self.bbox.show()
def copy(self, uri): filehash = hash_file(Gst.uri_get_location(uri)) thumbs_cache_dir = get_dir(os.path.join(xdg_cache_home(), "thumbs")) dbfile = os.path.join(thumbs_cache_dir, filehash) os.symlink(self._dbfile, dbfile)
def _show_preview(self, uri, info): self.log("Show preview for %s", uri) duration = info.get_duration() pretty_duration = beautify_length(duration) videos = info.get_video_streams() if videos: video = videos[0] if video.is_image(): self.current_preview_type = 'image' self.preview_video.hide() path = Gst.uri_get_location(uri) try: pixbuf = GdkPixbuf.Pixbuf.new_from_file(path) except GLib.Error as error: self.debug("Failed loading image because: %s", error) self._show_error(error.message) return False pixbuf_w = pixbuf.get_width() pixbuf_h = pixbuf.get_height() w, h = self.__get_best_size(pixbuf_w, pixbuf_h) pixbuf = pixbuf.scale_simple( w, h, GdkPixbuf.InterpType.NEAREST) self.preview_image.set_from_pixbuf(pixbuf) self.preview_image.set_size_request( self.settings.FCpreviewWidth, self.settings.FCpreviewHeight) self.preview_image.show() self.bbox.show() self.play_button.hide() self.seeker.hide() self.b_zoom_in.show() self.b_zoom_out.show() else: self.current_preview_type = 'video' self.preview_image.hide() self.player.setClipUri(self.current_selected_uri) self.player.setState(Gst.State.PAUSED) self.pos_adj.props.upper = duration video_width = ( video.get_par_num() / video.get_par_denom()) * video.get_width() video_height = video.get_height() w, h = self.__get_best_size(video_width, video_height) self.preview_video.set_size_request(w, h) aspect_ratio = video_width / video_height self.preview_video.setDisplayAspectRatio(aspect_ratio) self.preview_video.show() self.bbox.show() self.play_button.show() self.seeker.show() self.b_zoom_in.show() self.b_zoom_out.show() self.description = "\n".join([ _("<b>Resolution</b>: %d×%d") % ( video_width, video_height), _("<b>Duration</b>: %s") % pretty_duration]) else: self.current_preview_type = 'audio' self.preview_video.hide() audio = info.get_audio_streams() if not audio: self.debug("Audio has no streams") return False audio = audio[0] self.pos_adj.props.upper = duration self.preview_image.set_from_icon_name( "audio-x-generic", Gtk.IconSize.DIALOG) self.preview_image.show() self.preview_image.set_size_request(PREVIEW_WIDTH, PREVIEW_HEIGHT) self.description = "\n".join([ beautify_stream(audio), _("<b>Duration</b>: %s") % pretty_duration]) self.player.setState(Gst.State.NULL) self.player.setClipUri(self.current_selected_uri) self.player.setState(Gst.State.PAUSED) self.play_button.show() self.seeker.show() self.b_zoom_in.hide() self.b_zoom_out.hide() self.bbox.show() return True
def get_wavefile_location_for_uri(uri): """Computes the URI where the wave.npy file should be stored.""" filename = hash_file(Gst.uri_get_location(uri)) + ".wave.npy" cache_dir = get_dir(os.path.join(xdg_cache_home(), "waves")) return os.path.join(cache_dir, filename)