예제 #1
0
    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")
예제 #2
0
    def _setScenarioFile(self, uri):
        if 'PITIVI_SCENARIO_FILE' in os.environ:
            uri = quote_uri(os.environ['PITIVI_SCENARIO_FILE'])
        else:
            cache_dir = get_dir(os.path.join(xdg_cache_home(), "scenarios"))
            scenario_name = str(time.strftime("%Y%m%d-%H%M%S"))
            project_path = None
            if uri:
                project_path = path_from_uri(uri)
                scenario_name += os.path.splitext(
                    project_path.replace(os.sep, "_"))[0]

            uri = os.path.join(cache_dir, scenario_name + ".scenario")
            uri = quote_uri(uri)

        self._scenario_file = open(path_from_uri(uri), "w")

        if project_path:
            f = open(project_path)
            content = f.read()
            if not uri.endswith(".scenario"):
                self.write_action(
                    "load-project",
                    {"serialized-content": "%s" % content.replace("\n", "")})
            f.close()
예제 #3
0
    def _set_scenario_file(self, uri):
        if uri:
            project_path = path_from_uri(uri)
        else:
            # New project.
            project_path = None
        if 'PITIVI_SCENARIO_FILE' in os.environ:
            scenario_path = os.environ['PITIVI_SCENARIO_FILE']
        else:
            cache_dir = xdg_cache_home("scenarios")
            scenario_name = str(time.strftime("%Y%m%d-%H%M%S"))
            if project_path:
                scenario_name += os.path.splitext(
                    project_path.replace(os.sep, "_"))[0]
            scenario_path = os.path.join(cache_dir,
                                         scenario_name + ".scenario")

        scenario_path = path_from_uri(quote_uri(scenario_path))
        self._scenario_file = open(scenario_path, "w")

        if project_path and not project_path.endswith(".scenario"):
            # It's an xges file probably.
            with open(project_path) as project:
                content = project.read().replace("\n", "")
                self.write_action("load-project", serialized_content=content)
예제 #4
0
    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
예제 #5
0
    def _schedule_next_thumb_generation(self):
        """Schedules the generation of the next thumbnail, or stop.

        Checks the CPU usage and adjusts the waiting time at which the next
        thumbnail will be generated +/- 10%. Even then, it will only
        happen when the gobject loop is idle to avoid blocking the UI.
        """
        if self._thumb_cb_id is not None:
            # A thumb has already been scheduled.
            return

        if not self.queue:
            # Nothing left to do.
            self.debug("Thumbnails generation complete")
            self.stop_generation()
            return

        usage_percent = self.cpu_usage_tracker.usage()
        if usage_percent < self._max_cpu_usage:
            self.interval *= 0.9
            self.log("Thumbnailing sped up to a %.1f ms interval for `%s`",
                     self.interval, path_from_uri(self.uri))
        else:
            self.interval *= 1.1
            self.log("Thumbnailing slowed down to a %.1f ms interval for `%s`",
                     self.interval, path_from_uri(self.uri))
        self.cpu_usage_tracker.reset()
        self._thumb_cb_id = GLib.timeout_add(self.interval,
                                             self._create_next_thumb_cb,
                                             priority=GLib.PRIORITY_LOW)
예제 #6
0
파일: common.py 프로젝트: ue90/pitivi
def cloned_sample(*samples):
    """Gets a context manager which commits the transaction at the end."""
    with tempfile.TemporaryDirectory() as tmpdir:
        module = globals()
        original_get_sample_uri = module["get_sample_uri"]
        module["get_sample_uri"] = lambda sample: original_get_sample_uri(sample, samples_dir=tmpdir)
        try:
            for sample in samples:
                sample_path = path_from_uri(original_get_sample_uri(sample))
                clone_path = path_from_uri(get_sample_uri(sample))
                shutil.copyfile(sample_path, clone_path)
            yield tmpdir
        finally:
            module["get_sample_uri"] = original_get_sample_uri
예제 #7
0
파일: ui.py 프로젝트: cmutti/pitivi
def beautify_info(info):
    """
    Formats the specified info for display.

    @type info: L{DiscovererInfo}
    """
    ranks = {DiscovererVideoInfo: 0, DiscovererAudioInfo: 1, DiscovererStreamInfo: 2}

    def stream_sort_key(stream):
        try:
            return ranks[type(stream)]
        except KeyError:
            return len(ranks)

    info.get_stream_list().sort(key=stream_sort_key)
    nice_streams_txts = []
    for stream in info.get_stream_list():
        try:
            beautified_string = beautify_stream(stream)
        except NotImplementedError:
            doLog(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
            continue
        if beautified_string:
            nice_streams_txts.append(beautified_string)

    return "<b>" + path_from_uri(info.get_uri()) + "</b>\n" + "\n".join(nice_streams_txts)
예제 #8
0
파일: render.py 프로젝트: dz0ny/pitivi
    def _getFilesizeEstimate(self):
        """Estimates the final file size.

        Estimates in megabytes (over 30 MB) are rounded to the nearest 10 MB
        to smooth out small variations. You'd be surprised how imprecision can
        improve perceived accuracy.

        Returns:
            str: A human-readable (ex: "14 MB") estimate for the file size.
        """
        if not self.current_position or self.current_position == 0:
            return None

        current_filesize = os.stat(path_from_uri(self.outfile)).st_size
        length = self.project.ges_timeline.props.duration
        estimated_size = float(
            current_filesize * float(length) / self.current_position)
        # Now let's make it human-readable (instead of octets).
        # If it's in the giga range (10⁹) instead of mega (10⁶), use 2 decimals
        if estimated_size > 10e8:
            gigabytes = estimated_size / (10 ** 9)
            return _("%.2f GB" % gigabytes)
        else:
            megabytes = int(estimated_size / (10 ** 6))
            if megabytes > 30:
                megabytes = int(round(megabytes, -1))  # -1 means round to 10
            return _("%d MB" % megabytes)
예제 #9
0
파일: render.py 프로젝트: tomak-git/pitivi
    def _getFilesizeEstimate(self):
        """
        Using the current render output's filesize and position in the timeline,
        return a human-readable (ex: "14 MB") estimate of the final filesize.

        Estimates in megabytes (over 30 MB) are rounded to the nearest 10 MB
        to smooth out small variations. You'd be surprised how imprecision can
        improve perceived accuracy.
        """
        if not self.current_position or self.current_position == 0:
            return None

        current_filesize = os.stat(path_from_uri(self.outfile)).st_size
        length = self.app.project_manager.current_project.timeline.props.duration
        estimated_size = float(current_filesize * float(length) /
                               self.current_position)
        # Now let's make it human-readable (instead of octets).
        # If it's in the giga range (10⁹) instead of mega (10⁶), use 2 decimals
        if estimated_size > 10e8:
            gigabytes = estimated_size / (10**9)
            return _("%.2f GB" % gigabytes)
        else:
            megabytes = int(estimated_size / (10**6))
            if megabytes > 30:
                megabytes = int(round(megabytes, -1))  # -1 means round to 10
            return _("%d MB" % megabytes)
예제 #10
0
    def _launchPipeline(self):
        self.debug('Now generating waveforms for: %s',
                   path_from_uri(self._uri))
        self.pipeline = Gst.parse_launch("uridecodebin name=decode uri=" +
                                         self._uri + " ! waveformbin name=wave"
                                         " ! fakesink qos=false name=faked")
        # This line is necessary so we can instantiate GstTranscoder's
        # GstCpuThrottlingClock below.
        Gst.ElementFactory.make("uritranscodebin", None)
        clock = GObject.new(GObject.type_from_name("GstCpuThrottlingClock"))
        clock.props.cpu_usage = self._max_cpu_usage
        self.pipeline.use_clock(clock)
        faked = self.pipeline.get_by_name("faked")
        faked.props.sync = True
        self._wavebin = self.pipeline.get_by_name("wave")
        asset = self.ges_elem.get_asset().get_filesource_asset()
        self._wavebin.props.uri = asset.get_id()
        self._wavebin.props.duration = asset.get_duration()
        decode = self.pipeline.get_by_name("decode")
        decode.connect("autoplug-select", self._autoplug_select_cb)
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()

        self.n_samples = asset.get_duration() / SAMPLE_DURATION
        bus.connect("message", self._busMessageCb)
예제 #11
0
    def _create_next_thumb(self):
        if not self.wishlist or not self.queue:
            # nothing left to do
            self.debug("Thumbnails generation complete")
            self.stopGeneration()
            self.thumb_cache.commit()
            return
        else:
            self.debug("Missing %d thumbs", len(self.wishlist))

        wish = self._get_wish()
        if wish:
            time = wish
            self.queue.remove(wish)
        else:
            time = self.queue.pop(0)
        self.log('Creating thumb for "%s"', path_from_uri(self.uri))
        # append the time to the end of the queue so that if this seek fails
        # another try will be started later
        self.queue.append(time)
        self.pipeline.seek(1.0, Gst.Format.TIME,
                           Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
                           Gst.SeekType.SET, time, Gst.SeekType.NONE, -1)

        # Remove the GSource
        self._thumb_cb_id = None
        return False
예제 #12
0
파일: project.py 프로젝트: cymacs/pitivi
 def _cleanBackup(self, uri):
     if uri is None:
         return
     path = path_from_uri(self._makeBackupURI(uri))
     if os.path.exists(path):
         os.remove(path)
         self.debug('Removed backup file "%s"' % path)
예제 #13
0
    def _startThumbnailing(self):
        if not self.pipeline:
            # Can happen if stopGeneration is called because the clip has been
            # removed from the timeline after the PreviewGeneratorManager
            # started this job.
            return

        self.debug('Now generating thumbnails for: %s',
                   path_from_uri(self.uri))
        query_success, duration = self.pipeline.query_duration(Gst.Format.TIME)
        if not query_success or duration == -1:
            self.debug("Could not determine duration of: %s", self.uri)
            duration = self.ges_elem.props.duration

        self.queue = list(range(0, duration, self.thumb_period))

        self._checkCPU()

        # Save periodically to avoid the common situation where the user exits
        # the app before a long clip has been fully thumbnailed.
        # Spread timeouts between 30-80 secs to avoid concurrent disk writes.
        random_time = random.randrange(30, 80)
        GLib.timeout_add_seconds(random_time, self._autosave)

        # Remove the GSource
        return False
예제 #14
0
    def _startThumbnailing(self):
        if not self.pipeline:
            # Can happen if stopGeneration is called because the clip has been
            # removed from the timeline after the PreviewGeneratorManager
            # started this job.
            return

        self.debug(
            'Now generating thumbnails for: %s', path_from_uri(self.uri))
        query_success, duration = self.pipeline.query_duration(Gst.Format.TIME)
        if not query_success or duration == -1:
            self.debug("Could not determine duration of: %s", self.uri)
            duration = self.ges_elem.props.duration

        self.queue = list(range(0, duration, self.thumb_period))

        self._checkCPU()

        # Save periodically to avoid the common situation where the user exits
        # the app before a long clip has been fully thumbnailed.
        # Spread timeouts between 30-80 secs to avoid concurrent disk writes.
        random_time = random.randrange(30, 80)
        GLib.timeout_add_seconds(random_time, self._autosave)

        # Remove the GSource
        return False
예제 #15
0
    def _create_next_thumb(self):
        if not self.wishlist or not self.queue:
            # nothing left to do
            self.debug("Thumbnails generation complete")
            self.stopGeneration()
            self.thumb_cache.commit()
            return
        else:
            self.debug("Missing %d thumbs", len(self.wishlist))

        wish = self._get_wish()
        if wish:
            time = wish
            self.queue.remove(wish)
        else:
            time = self.queue.pop(0)
        self.log('Creating thumb for "%s"', path_from_uri(self.uri))
        # append the time to the end of the queue so that if this seek fails
        # another try will be started later
        self.queue.append(time)
        self.pipeline.seek(1.0,
                           Gst.Format.TIME, Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
                           Gst.SeekType.SET, time,
                           Gst.SeekType.NONE, -1)

        # Remove the GSource
        self._thumb_cb_id = None
        return False
예제 #16
0
    def _launchPipeline(self):
        self.debug(
            'Now generating waveforms for: %s', path_from_uri(self._uri))
        self.pipeline = Gst.parse_launch("uridecodebin name=decode uri=" +
                                         self._uri + " ! waveformbin name=wave"
                                         " ! fakesink qos=false name=faked")
        # This line is necessary so we can instantiate GstTranscoder's
        # GstCpuThrottlingClock below.
        Gst.ElementFactory.make("uritranscodebin", None)
        clock = GObject.new(GObject.type_from_name("GstCpuThrottlingClock"))
        clock.props.cpu_usage = self._max_cpu_usage
        self.pipeline.use_clock(clock)
        faked = self.pipeline.get_by_name("faked")
        faked.props.sync = True
        self._wavebin = self.pipeline.get_by_name("wave")
        asset = self.ges_elem.get_parent().get_asset()
        self._wavebin.props.uri = asset.get_id()
        self._wavebin.props.duration = asset.get_duration()
        decode = self.pipeline.get_by_name("decode")
        decode.connect("autoplug-select", self._autoplug_select_cb)
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()

        asset = self.ges_elem.get_parent().get_asset()
        self.n_samples = asset.get_duration() / SAMPLE_DURATION
        bus.connect("message", self._busMessageCb)
예제 #17
0
파일: ui.py 프로젝트: tomak-git/pitivi
def beautify_info(info):
    """
    Formats the specified info for display.

    @type info: L{DiscovererInfo}
    """
    ranks = {
        DiscovererVideoInfo: 0,
        DiscovererAudioInfo: 1,
        DiscovererStreamInfo: 2
    }

    def stream_sort_key(stream):
        try:
            return ranks[type(stream)]
        except KeyError:
            return len(ranks)

    info.get_stream_list().sort(key=stream_sort_key)
    nice_streams_txts = []
    for stream in info.get_stream_list():
        try:
            beautified_string = beautify_stream(stream)
        except NotImplementedError:
            doLog(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
            continue
        if beautified_string:
            nice_streams_txts.append(beautified_string)

    return ("<b>" + path_from_uri(info.get_uri()) + "</b>\n" +
        "\n".join(nice_streams_txts))
예제 #18
0
    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

        if not self.thumb_width:
            self.debug("Finding thumb width")
            self._setup_pipeline()
            return False

        # 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._setup_pipeline()
        else:
            self.emit("done")

        # Stop calling me, I started already.
        return False
예제 #19
0
    def _project_manager_new_project_loaded_cb(self, project_manager, project):
        """Connects the UI to the specified project.

        Args:
            project_manager (ProjectManager): The project manager.
            project (Project): The project which has been loaded.
        """
        self.log("A new project has been loaded")

        self._connect_to_project(project)
        project.pipeline.activate_position_listener()

        self.viewer.set_project(project)
        self.clipconfig.set_project(project, self.timeline_ui)
        self.timeline_ui.set_project(project)

        # When creating a blank project there's no project URI yet.
        if project.uri:
            folder_path = os.path.dirname(path_from_uri(project.uri))
            self.settings.lastProjectFolder = folder_path

        self.update_title()

        if project_manager.disable_save is True:
            # Special case: we enforce "Save as", but the normal "Save" button
            # redirects to it if needed, so we still want it to be enabled:
            self.save_action.set_enabled(True)

        if project.ges_timeline.props.duration != 0:
            self.render_button.set_sensitive(True)
예제 #20
0
파일: project.py 프로젝트: palango/pitivi
    def loadProject(self, uri):
        """
        Load the given URI as a project. If a backup file exists, ask if it
        should be loaded instead, and if so, force the user to use "Save as"
        afterwards.
        """
        if self.current is not None and not self.closeRunningProject():
            return False

        self.emit("new-project-loading", uri)

        # We really want a path for os.path to work
        path = path_from_uri(uri)
        backup_path = self._makeBackupURI(path_from_uri(uri))
        use_backup = False
        try:
            time_diff = os.path.getmtime(backup_path) - os.path.getmtime(path)
            self.debug('Backup file "%s" is %d secs newer' % (backup_path, time_diff))
        except OSError:
            self.debug('Backup file "%s" does not exist' % backup_path)
        else:
            if time_diff > 0:
                use_backup = self._restoreFromBackupDialog(time_diff)
        if use_backup:
            uri = self._makeBackupURI(uri)
            self.debug('Loading project from backup "%s"' % uri)
            # Make a new project instance, but don't specify the URI.
            # That way, we force the user to "Save as" (which ensures that the
            # changes in the loaded backup file are approved by the user).
            self.current = Project()
        else:
            # Load the project normally.
            # The "old" backup file will eventually be deleted or overwritten.
            self.current = Project(uri=uri)

        self.emit("new-project-created", self.current)

        timeline = self.current.timeline
        self.formatter = GES.PitiviFormatter()
        self.formatter.connect("source-moved", self._formatterMissingURICb)
        self.formatter.connect("loaded", self._projectLoadedCb)
        if self.formatter.load_from_uri(timeline, uri):
            self.current.connect("project-changed", self._projectChangedCb)
            return True
        self.warn("Could not load project %s", uri)
        return False
예제 #21
0
    def _addAsset(self, asset):
        # 128 is the normal size for thumbnails, but for *icons* it looks insane
        LARGE_SIZE = 96
        info = asset.get_info()

        # The code below tries to read existing thumbnails from the freedesktop
        # thumbnails directory (~/.thumbnails). The filenames are simply
        # the file URI hashed with md5, so we can retrieve them easily.
        video_streams = [i for i in info.get_stream_list() if isinstance(i, DiscovererVideoInfo)]
        if len(video_streams) > 0:
            # From the freedesktop spec: "if the environment variable
            # $XDG_CACHE_HOME is set and not blank then the directory
            # $XDG_CACHE_HOME/thumbnails will be used, otherwise
            # $HOME/.cache/thumbnails will be used."
            # Older version of the spec also mentioned $HOME/.thumbnails
            quoted_uri = quote_uri(info.get_uri())
            thumbnail_hash = md5(quoted_uri).hexdigest()
            try:
                thumb_dir = os.environ['XDG_CACHE_HOME']
                thumb_64, thumb_128 = self._getThumbnailInDir(thumb_dir, thumbnail_hash)
            except KeyError:
                thumb_64, thumb_128 = (None, None)
            if thumb_64 is None:
                thumb_dir = os.path.expanduser("~/.cache/thumbnails/")
                thumb_64, thumb_128 = self._getThumbnailInDir(thumb_dir, thumbnail_hash)
            if thumb_64 is None:
                thumb_dir = os.path.expanduser("~/.thumbnails/")
                thumb_64, thumb_128 = self._getThumbnailInDir(thumb_dir, thumbnail_hash)
            if thumb_64 is None:
                if asset.is_image():
                    thumb_64 = self._getIcon("image-x-generic")
                    thumb_128 = self._getIcon("image-x-generic", None, LARGE_SIZE)
                else:
                    thumb_64 = self._getIcon("video-x-generic")
                    thumb_128 = self._getIcon("video-x-generic", None, LARGE_SIZE)
                # TODO ideally gst discoverer should create missing thumbnails.
                self.log("Missing a thumbnail for %s, queuing", path_from_uri(quoted_uri))
                self._missing_thumbs.append(quoted_uri)
        else:
            thumb_64 = self._getIcon("audio-x-generic")
            thumb_128 = self._getIcon("audio-x-generic", None, LARGE_SIZE)

        if info.get_duration() == Gst.CLOCK_TIME_NONE:
            duration = ''
        else:
            duration = beautify_length(info.get_duration())

        name = info_name(info)

        self.pending_rows.append((thumb_64,
                                  thumb_128,
                                  beautify_info(info),
                                  asset,
                                  info.get_uri(),
                                  duration,
                                  name))
        if len(self.pending_rows) > 50:
            self.flush_pending_rows()
예제 #22
0
    def test_backup_project(self):
        self.manager.new_blank_project()

        # Assign an uri to the project where it's saved by default.
        unused, xges_path = tempfile.mkstemp(suffix=".xges")
        uri = "file://" + os.path.abspath(xges_path)
        self.manager.current_project.uri = uri
        # This is where the automatic backup file is saved.
        backup_uri = self.manager._make_backup_uri(uri)

        # Save the backup
        self.assertTrue(self.manager.save_project(
            self.manager.current_project, backup=True))
        self.assertTrue(os.path.isfile(path_from_uri(backup_uri)))

        self.manager.close_running_project()
        self.assertFalse(os.path.isfile(path_from_uri(backup_uri)),
                         "Backup file not deleted when project closed")
예제 #23
0
    def testBackupProject(self):
        self.manager.new_blank_project()

        # Assign an uri to the project where it's saved by default.
        unused, xges_path = tempfile.mkstemp(suffix=".xges")
        uri = "file://" + os.path.abspath(xges_path)
        self.manager.current_project.uri = uri
        # This is where the automatic backup file is saved.
        backup_uri = self.manager._makeBackupURI(uri)

        # Save the backup
        self.assertTrue(self.manager.saveProject(
            self.manager.current_project, backup=True))
        self.assertTrue(os.path.isfile(path_from_uri(backup_uri)))

        self.manager.closeRunningProject()
        self.assertFalse(os.path.isfile(path_from_uri(backup_uri)),
                         "Backup file not deleted when project closed")
예제 #24
0
    def _schedule_next_thumb_generation(self):
        """Schedules the generation of the next thumbnail.

        Checks the CPU usage and adjusts the waiting time at which the next
        thumbnail will be generated +/- 10%. Even then, it will only
        happen when the gobject loop is idle to avoid blocking the UI.
        """
        usage_percent = self.cpu_usage_tracker.usage()
        if usage_percent < self._max_cpu_usage:
            self.interval *= 0.9
            self.log("Thumbnailing sped up to a %.1f ms interval for `%s`",
                     self.interval, path_from_uri(self.uri))
        else:
            self.interval *= 1.1
            self.log("Thumbnailing slowed down to a %.1f ms interval for `%s`",
                     self.interval, path_from_uri(self.uri))
        self.cpu_usage_tracker.reset()
        self._thumb_cb_id = GLib.timeout_add(self.interval,
                                             self._create_next_thumb_cb,
                                             priority=GLib.PRIORITY_LOW)
예제 #25
0
파일: project.py 프로젝트: cymacs/pitivi
    def _allSourcesInHomedir(self, sources):
        """
        Checks if all sources are located in the users home directory
        """
        homedir = os.path.expanduser("~")

        for source in sources:
            if not path_from_uri(source.get_uri()).startswith(homedir):
                return False

        return True
예제 #26
0
파일: project.py 프로젝트: cymacs/pitivi
    def exportProject(self, project, uri):
        """
        Export a project to a *.tar archive which includes the project file
        and all sources
        """
        # write project file to temporary file
        project_name = project.name if project.name else "project"
        tmp_name = "%s.xptv" % project_name

        try:
            directory = os.path.dirname(uri)
            tmp_uri = os.path.join(directory, tmp_name)
            self.saveProject(project, tmp_uri, overwrite=True)

            # create tar file
            with tarfile.open(path_from_uri(uri), mode="w") as tar:
                # top directory in tar-file
                top = "%s-export" % project_name
                # add temporary project file
                tar.add(path_from_uri(tmp_uri), os.path.join(top, tmp_name))

                # get common path
                sources = project.medialibrary.getSources()
                if self._allSourcesInHomedir(sources):
                    common = os.path.expanduser("~")
                else:
                    common = "/"

                # add all sources
                for source in sources:
                    path = path_from_uri(source.get_uri())
                    tar.add(path, os.path.join(top, os.path.relpath(path, common)))
                tar.close()

            # remove temporary file
            os.remove(path_from_uri(tmp_uri))
        except:
            return False

        return True
예제 #27
0
    def _checkCPU(self):
        """Adjusts when the next thumbnail is generated.

        Checks the CPU usage and adjusts the waiting time at which the next
        thumbnail will be generated +/- 10%. Even then, it will only
        happen when the gobject loop is idle to avoid blocking the UI.
        """
        usage_percent = self.cpu_usage_tracker.usage()
        if usage_percent < THUMBNAILS_CPU_USAGE:
            self.interval *= 0.9
            self.log(
                'Thumbnailing sped up (+10%%) to a %.1f ms interval for "%s"',
                self.interval, path_from_uri(self.uri))
        else:
            self.interval *= 1.1
            self.log(
                'Thumbnailing slowed down (-10%%) to a %.1f ms interval for "%s"',
                self.interval, path_from_uri(self.uri))
        self.cpu_usage_tracker.reset()
        self._thumb_cb_id = GLib.timeout_add(self.interval,
                                             self._create_next_thumb,
                                             priority=GLib.PRIORITY_LOW)
예제 #28
0
파일: previewers.py 프로젝트: jojva/pitivi
 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)")
예제 #29
0
    def _checkCPU(self):
        """Adjusts when the next thumbnail is generated.

        Checks the CPU usage and adjusts the waiting time at which the next
        thumbnail will be generated +/- 10%. Even then, it will only
        happen when the gobject loop is idle to avoid blocking the UI.
        """
        usage_percent = self.cpu_usage_tracker.usage()
        if usage_percent < self._max_cpu_usage:
            self.interval *= 0.9
            self.log(
                'Thumbnailing sped up (+10%%) to a %.1f ms interval for "%s"',
                self.interval, path_from_uri(self.uri))
        else:
            self.interval *= 1.1
            self.log(
                'Thumbnailing slowed down (-10%%) to a %.1f ms interval for "%s"',
                self.interval, path_from_uri(self.uri))
        self.cpu_usage_tracker.reset()
        self._thumb_cb_id = GLib.timeout_add(self.interval,
                                             self._create_next_thumb,
                                             priority=GLib.PRIORITY_LOW)
예제 #30
0
    def _setScenarioFile(self, uri):
        if 'PITIVI_SCENARIO_FILE' in os.environ:
            uri = quote_uri(os.environ['PITIVI_SCENARIO_FILE'])
        else:
            cache_dir = get_dir(os.path.join(xdg_cache_home(), "scenarios"))
            scenario_name = str(time.strftime("%Y%m%d-%H%M%S"))
            project_path = None
            if uri:
                project_path = path_from_uri(uri)
                scenario_name += os.path.splitext(project_path.replace(os.sep, "_"))[0]

            uri = os.path.join(cache_dir, scenario_name + ".scenario")
            uri = quote_uri(uri)

        self._scenario_file = open(path_from_uri(uri), "w")

        if project_path:
            f = open(project_path)
            content = f.read()
            self.write_action("load-project",
                              {"serialized-content":
                               "%s" % content.replace("\n", "")})
            f.close()
예제 #31
0
파일: previewers.py 프로젝트: jojva/pitivi
 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)")
예제 #32
0
    def _setScenarioFile(self, uri):
        if uri:
            project_path = path_from_uri(uri)
        else:
            # New project.
            project_path = None
        if 'PITIVI_SCENARIO_FILE' in os.environ:
            scenario_path = os.environ['PITIVI_SCENARIO_FILE']
        else:
            cache_dir = get_dir(os.path.join(xdg_cache_home(), "scenarios"))
            scenario_name = str(time.strftime("%Y%m%d-%H%M%S"))
            if project_path:
                scenario_name += os.path.splitext(project_path.replace(os.sep, "_"))[0]
            scenario_path = os.path.join(cache_dir, scenario_name + ".scenario")

        scenario_path = path_from_uri(quote_uri(scenario_path))
        self._scenario_file = open(scenario_path, "w")

        if project_path and not project_path.endswith(".scenario"):
            # It's an xges file probably.
            with open(project_path) as project:
                content = project.read().replace("\n", "")
                self.write_action("load-project",
                                  serialized_content=content)
예제 #33
0
    def _setProject(self, project):
        """Disconnects and then reconnects callbacks to the specified project.

        Args:
            project (Project): The new current project.
        """
        if not project:
            self.warning("Current project instance does not exist")
            return False

        self.clipconfig.project = project

        # When creating a blank project there's no project URI yet.
        if project.uri:
            folder_path = os.path.dirname(path_from_uri(project.uri))
            self.settings.lastProjectFolder = folder_path
예제 #34
0
    def _setProject(self, project):
        """Disconnects and then reconnects callbacks to the specified project.

        Args:
            project (Project): The new current project.
        """
        if not project:
            self.warning("Current project instance does not exist")
            return False

        self.clipconfig.project = project

        # When creating a blank project there's no project URI yet.
        if project.uri:
            folder_path = os.path.dirname(path_from_uri(project.uri))
            self.settings.lastProjectFolder = folder_path
예제 #35
0
파일: ui.py 프로젝트: isabella232/pitivi
def beautify_asset(asset):
    """Formats the specified asset for display.

    Args:
        asset (GES.Asset): The asset to display.
    """
    from pitivi.utils.proxy import get_proxy_target
    uri = get_proxy_target(asset).props.id
    path = path_from_uri(uri)
    res = ["<b>" + GLib.markup_escape_text(path) + "</b>"]

    ranks = {
        DiscovererVideoInfo: 0,
        DiscovererAudioInfo: 1,
        DiscovererStreamInfo: 2
    }

    def stream_sort_key(stream):
        try:
            return ranks[type(stream)]
        except KeyError:
            return len(ranks)

    info = asset.get_info()
    streams = info.get_stream_list()
    streams.sort(key=stream_sort_key)
    for stream in streams:
        try:
            beautified_string = beautify_stream(stream)
        except NotImplementedError:
            do_log(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
            continue
        if beautified_string:
            res.append(beautified_string)

    duration = beautify_length(asset.get_duration())
    if duration:
        res.append(_("<b>Duration:</b> %s") % duration)

    if asset.creation_progress < 100:
        res.append(
            _("<b>Proxy creation progress:</b> %d%%") %
            asset.creation_progress)

    return "\n".join(res)
예제 #36
0
    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
예제 #37
0
파일: ui.py 프로젝트: pitivi/pitivi
def beautify_asset(asset):
    """Formats the specified asset for display.

    Args:
        asset (GES.Asset): The asset to display.
    """
    uri = get_proxy_target(asset).props.id
    path = path_from_uri(uri)
    res = ["<b>" + GLib.markup_escape_text(path) + "</b>"]

    ranks = {
        DiscovererVideoInfo: 0,
        DiscovererAudioInfo: 1,
        DiscovererStreamInfo: 2
    }

    def stream_sort_key(stream):
        try:
            return ranks[type(stream)]
        except KeyError:
            return len(ranks)

    info = asset.get_info()
    streams = info.get_stream_list()
    streams.sort(key=stream_sort_key)
    for stream in streams:
        try:
            beautified_string = beautify_stream(stream)
        except NotImplementedError:
            doLog(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
            continue
        if beautified_string:
            res.append(beautified_string)

    duration = beautify_length(asset.get_duration())
    if duration:
        res.append(_("<b>Duration:</b> %s") % duration)

    if asset.creation_progress < 100:
        res.append(_("<b>Proxy creation progress:</b> %d%%") % asset.creation_progress)

    return "\n".join(res)
예제 #38
0
파일: ui.py 프로젝트: pitivi/pitivi
def beautify_missing_asset(asset):
    """Formats the specified missing asset for display.

    Args:
        asset (GES.UriClipAsset): The asset to display.
    """
    uri = asset.get_id()
    path = path_from_uri(uri)
    res = [_("<b>Path</b>: %s") % GLib.markup_escape_text(path)]

    duration = beautify_length(asset.get_duration())
    if duration:
        res.append(_("<b>Duration</b>: %s") % duration)

    size = asset.get_meta("file-size")
    if size:
        file_size = GLib.format_size_full(size, GLib.FormatSizeFlags.LONG_FORMAT)
        res.append(_("<b>Size</b>: %s") % file_size)

    return "\n".join(res)
예제 #39
0
 def _generateThumbnails(self, uri):
     if not self.thumbnailer:
         # TODO: Use thumbnails generated with GStreamer.
         return None
     # This way of getting the mimetype feels awfully convoluted but
     # seems to be the proper/reliable way in a GNOME context
     asset_file = Gio.file_new_for_uri(uri)
     info = asset_file.query_info(attributes="standard::*", flags=Gio.FileQueryInfoFlags.NONE, cancellable=None)
     mime = Gio.content_type_get_mime_type(info.get_content_type())
     mtime = os.path.getmtime(path_from_uri(uri))
     if not self.thumbnailer.can_thumbnail(uri, mime, mtime):
         self.debug("Thumbnailer says it can't thumbnail %s", uri)
         return None
     pixbuf_128 = self.thumbnailer.generate_thumbnail(uri, mime)
     if not pixbuf_128:
         self.debug("Thumbnailer failed thumbnailing %s", uri)
         return None
     self.thumbnailer.save_thumbnail(pixbuf_128, uri, mtime)
     pixbuf_64 = pixbuf_128.scale_simple(64, 64, GdkPixbuf.InterpType.BILINEAR)
     return pixbuf_128, pixbuf_64
예제 #40
0
def beautify_missing_asset(asset):
    """Formats the specified missing asset for display.

    Args:
        asset (GES.UriClipAsset): The asset to display.
    """
    uri = asset.get_id()
    path = path_from_uri(uri)
    res = [_("<b>Path</b>: %s") % GLib.markup_escape_text(path)]

    duration = beautify_length(asset.get_duration())
    if duration:
        res.append(_("<b>Duration</b>: %s") % duration)

    size = asset.get_meta("file-size")
    if size:
        file_size = GLib.format_size_full(size, GLib.FormatSizeFlags.LONG_FORMAT)
        res.append(_("<b>Size</b>: %s") % file_size)

    return "\n".join(res)
예제 #41
0
파일: previewers.py 프로젝트: cfoch/pitivi
    def _launchPipeline(self):
        self.debug(
            'Now generating waveforms for: %s', path_from_uri(self._uri))
        self.pipeline = Gst.parse_launch("uridecodebin name=decode uri=" +
                                         self._uri + " ! waveformbin name=wave"
                                         " ! fakesink qos=false name=faked")
        faked = self.pipeline.get_by_name("faked")
        faked.props.sync = True
        self._wavebin = self.pipeline.get_by_name("wave")
        asset = self.ges_elem.get_parent().get_asset()
        self._wavebin.props.uri = asset.get_id()
        self._wavebin.props.duration = asset.get_duration()
        decode = self.pipeline.get_by_name("decode")
        decode.connect("autoplug-select", self._autoplugSelectCb)
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()

        asset = self.ges_elem.get_parent().get_asset()
        self.n_samples = asset.get_duration() / SAMPLE_DURATION
        bus.connect("message", self._busMessageCb)
        self.becomeControlled()
예제 #42
0
    def _create_next_thumb_cb(self):
        """Creates a missing thumbnail."""
        self._thumb_cb_id = None
        if not self.queue:
            # Nothing left to do.
            self.debug("Thumbnails generation complete")
            self.stop_generation()
            # Stop calling me.
            return False

        position = self.queue.pop(0)
        self.log("Creating thumb for `%s` at %s", path_from_uri(self.uri),
                 position)
        self.pipeline.seek(1.0, Gst.Format.TIME,
                           Gst.SeekFlags.FLUSH | Gst.SeekFlags.ACCURATE,
                           Gst.SeekType.SET, position, Gst.SeekType.NONE, -1)

        # Stop calling me.
        # The seek operation will generate an ASYNC_DONE message on the bus,
        # and then the next thumbnail generation operation will be scheduled.
        return False
예제 #43
0
    def _launchPipeline(self):
        self.debug('Now generating waveforms for: %s',
                   path_from_uri(self._uri))
        self.pipeline = Gst.parse_launch("uridecodebin name=decode uri=" +
                                         self._uri + " ! waveformbin name=wave"
                                         " ! fakesink qos=false name=faked")
        faked = self.pipeline.get_by_name("faked")
        faked.props.sync = True
        self._wavebin = self.pipeline.get_by_name("wave")
        asset = self.ges_elem.get_parent().get_asset()
        self._wavebin.props.uri = asset.get_id()
        self._wavebin.props.duration = asset.get_duration()
        decode = self.pipeline.get_by_name("decode")
        decode.connect("autoplug-select", self._autoplugSelectCb)
        bus = self.pipeline.get_bus()
        bus.add_signal_watch()

        asset = self.ges_elem.get_parent().get_asset()
        self.n_samples = asset.get_duration() / SAMPLE_DURATION
        bus.connect("message", self._busMessageCb)
        self.becomeControlled()
예제 #44
0
파일: ui.py 프로젝트: ignatenkobrain/pitivi
def beautify_asset(asset):
    """Formats the specified asset for display.

    Args:
        asset (GES.Asset): The asset to display.
    """
    ranks = {
        DiscovererVideoInfo: 0,
        DiscovererAudioInfo: 1,
        DiscovererStreamInfo: 2
    }

    def stream_sort_key(stream):
        try:
            return ranks[type(stream)]
        except KeyError:
            return len(ranks)

    info = asset.get_info()
    uri = get_proxy_target(asset).props.id
    info.get_stream_list().sort(key=stream_sort_key)
    nice_streams_txts = []
    for stream in info.get_stream_list():
        try:
            beautified_string = beautify_stream(stream)
        except NotImplementedError:
            doLog(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
            continue
        if beautified_string:
            nice_streams_txts.append(beautified_string)

    res = "<b>" + path_from_uri(uri) + "</b>\n" + "\n".join(nice_streams_txts)

    if asset.creation_progress < 100:
        res += _("\n<b>Proxy creation progress: ") + \
            "</b>%d%%" % asset.creation_progress

    return res
예제 #45
0
def beautify_asset(asset):
    """Formats the specified asset for display.

    Args:
        asset (GES.Asset): The asset to display.
    """
    ranks = {
        DiscovererVideoInfo: 0,
        DiscovererAudioInfo: 1,
        DiscovererStreamInfo: 2
    }

    def stream_sort_key(stream):
        try:
            return ranks[type(stream)]
        except KeyError:
            return len(ranks)

    info = asset.get_info()
    uri = get_proxy_target(asset).props.id
    info.get_stream_list().sort(key=stream_sort_key)
    nice_streams_txts = []
    for stream in info.get_stream_list():
        try:
            beautified_string = beautify_stream(stream)
        except NotImplementedError:
            doLog(ERROR, "Beautify", "None", "Cannot beautify %s", stream)
            continue
        if beautified_string:
            nice_streams_txts.append(beautified_string)

    res = "<b>" + path_from_uri(uri) + "</b>\n" + "\n".join(nice_streams_txts)

    if asset.creation_progress < 100:
        res += _("\n<b>Proxy creation progress: ") + \
            "</b>%d%%" % asset.creation_progress

    return res
예제 #46
0
 def _generateThumbnails(self, uri):
     if not self.thumbnailer:
         # TODO: Use thumbnails generated with GStreamer.
         return None
     # This way of getting the mimetype feels awfully convoluted but
     # seems to be the proper/reliable way in a GNOME context
     asset_file = Gio.file_new_for_uri(uri)
     info = asset_file.query_info(attributes="standard::*",
                                  flags=Gio.FileQueryInfoFlags.NONE,
                                  cancellable=None)
     mime = Gio.content_type_get_mime_type(info.get_content_type())
     mtime = os.path.getmtime(path_from_uri(uri))
     if not self.thumbnailer.can_thumbnail(uri, mime, mtime):
         self.debug("Thumbnailer says it can't thumbnail %s", uri)
         return None
     pixbuf_128 = self.thumbnailer.generate_thumbnail(uri, mime)
     if not pixbuf_128:
         self.debug("Thumbnailer failed thumbnailing %s", uri)
         return None
     self.thumbnailer.save_thumbnail(pixbuf_128, uri, mtime)
     pixbuf_64 = pixbuf_128.scale_simple(64, 64,
                                         GdkPixbuf.InterpType.BILINEAR)
     return pixbuf_128, pixbuf_64
예제 #47
0
파일: project.py 프로젝트: palango/pitivi
    def saveProject(self, project, uri=None, overwrite=False, formatter=None, backup=False):
        """
        Save the L{Project} to the given location.

        If specified, use the given formatter.

        @type project: L{Project}
        @param project: The L{Project} to save.
        @type uri: L{str}
        @param uri: The absolute URI of the location to store the project to.
        @param overwrite: Whether to overwrite existing location.
        @type overwrite: C{bool}
        @type formatter: L{Formatter}
        @param formatter: The L{Formatter} to use to store the project if specified.
        If it is not specified, then it will be saved at its original format.
        @param backup: Whether the requested save operation is for a backup
        @type backup: C{bool}

        @see: L{Formatter.saveProject}
        """
        if formatter is None:
            formatter = GES.PitiviFormatter()
        if backup:
            if project.uri and self.current.uri is not None:
                # Ignore whatever URI that is passed on to us. It's a trap.
                uri = self._makeBackupURI(project.uri)
            else:
                # Do not try to save backup files for blank projects.
                # It is possible that self.current.uri == None when the backup
                # timer sent us an old instance of the (now closed) project.
                return
        elif uri is None:
            # This allows calling saveProject without specifying the target URI
            uri = project.uri
        else:
            # Ensure the URI we are given is properly encoded, or GIO will fail
            uri = quote_uri(uri)

            # The following needs to happen before we change project.uri:
            if not isWritable(path_from_uri(uri)):
                # TODO: this will not be needed when GTK+ bug #601451 is fixed
                self.emit("save-project-failed", uri,
                        _("You do not have permissions to write to this folder."))
                return

            # Update the project instance's uri for the "Save as" scenario.
            # Otherwise, subsequent saves will be to the old uri.
            if not backup:
                project.uri = uri

        if uri is None or not formatter.can_save_uri(uri):
            self.emit("save-project-failed", uri,
                    _("Cannot save with this file format."))
            return

        if overwrite or not os.path.exists(path_from_uri(uri)):
            formatter.set_sources(project.medialibrary.getSources())
            saved = formatter.save_to_uri(project.timeline, uri)
            if saved:
                if not backup:
                    # Do not emit the signal when autosaving a backup file
                    self.emit("project-saved", project, uri)
                    self.debug('Saved project "%s"' % uri)
                else:
                    self.debug('Saved backup "%s"' % uri)
            return saved
예제 #48
0
 def startLevelsDiscoveryWhenIdle(self):
     """Starts processing waveform (whenever possible)."""
     self.debug('Waiting for UI to become idle for: %s',
                path_from_uri(self._uri))
     GLib.idle_add(self._startLevelsDiscovery, priority=GLib.PRIORITY_LOW)
예제 #49
0
 def _startThumbnailingWhenIdle(self):
     self.debug(
         'Waiting for UI to become idle for: %s', path_from_uri(self.uri))
     GLib.idle_add(self._startThumbnailing, priority=GLib.PRIORITY_LOW)
예제 #50
0
 def _startThumbnailingWhenIdle(self):
     self.debug('Waiting for UI to become idle for: %s',
                path_from_uri(self.uri))
     GLib.idle_add(self._startThumbnailing, priority=GLib.PRIORITY_LOW)
예제 #51
0
    def _addAsset(self, asset):
        # 128 is the normal size for thumbnails, but for *icons* it looks
        # insane
        LARGE_SIZE = 96
        info = asset.get_info()

        # The code below tries to read existing thumbnails from the freedesktop
        # thumbnails directory (~/.thumbnails). The filenames are simply
        # the file URI hashed with md5, so we can retrieve them easily.
        video_streams = [
            i for i in info.get_stream_list()
            if isinstance(i, DiscovererVideoInfo)
        ]
        if len(video_streams) > 0:
            # From the freedesktop spec: "if the environment variable
            # $XDG_CACHE_HOME is set and not blank then the directory
            # $XDG_CACHE_HOME/thumbnails will be used, otherwise
            # $HOME/.cache/thumbnails will be used."
            # Older version of the spec also mentioned $HOME/.thumbnails
            quoted_uri = quote_uri(info.get_uri())
            thumbnail_hash = md5(quoted_uri.encode()).hexdigest()
            try:
                thumb_dir = os.environ['XDG_CACHE_HOME']
                thumb_64, thumb_128 = self._getThumbnailInDir(
                    thumb_dir, thumbnail_hash)
            except KeyError:
                thumb_64, thumb_128 = (None, None)
            if thumb_64 is None:
                thumb_dir = os.path.expanduser("~/.cache/thumbnails/")
                thumb_64, thumb_128 = self._getThumbnailInDir(
                    thumb_dir, thumbnail_hash)
            if thumb_64 is None:
                thumb_dir = os.path.expanduser("~/.thumbnails/")
                thumb_64, thumb_128 = self._getThumbnailInDir(
                    thumb_dir, thumbnail_hash)
            if thumb_64 is None:
                if asset.is_image():
                    thumb_64 = self._getIcon("image-x-generic")
                    thumb_128 = self._getIcon("image-x-generic", None,
                                              LARGE_SIZE)
                else:
                    thumb_64 = self._getIcon("video-x-generic")
                    thumb_128 = self._getIcon("video-x-generic", None,
                                              LARGE_SIZE)
                # TODO ideally gst discoverer should create missing thumbnails.
                self.log("Missing a thumbnail for %s, queuing",
                         path_from_uri(quoted_uri))
                self._missing_thumbs.append(quoted_uri)
        else:
            thumb_64 = self._getIcon("audio-x-generic")
            thumb_128 = self._getIcon("audio-x-generic", None, LARGE_SIZE)

        if info.get_duration() == Gst.CLOCK_TIME_NONE:
            duration = ''
        else:
            duration = beautify_length(info.get_duration())

        name = info_name(info)

        self.pending_rows.append((thumb_64, thumb_128, beautify_info(info),
                                  asset, info.get_uri(), duration, name))
        if len(self.pending_rows) > 50:
            self.flush_pending_rows()
예제 #52
0
파일: previewers.py 프로젝트: cfoch/pitivi
 def startLevelsDiscoveryWhenIdle(self):
     """Starts processing waveform (whenever possible)."""
     self.debug('Waiting for UI to become idle for: %s',
                path_from_uri(self._uri))
     GLib.idle_add(self._startLevelsDiscovery, priority=GLib.PRIORITY_LOW)
예제 #53
0
 def start_generation(self):
     self.debug("Waiting for UI to become idle for: %s",
                path_from_uri(self.uri))
     self.__start_id = GLib.idle_add(self._start_thumbnailing_cb,
                                     priority=GLib.PRIORITY_LOW)