예제 #1
0
    def __init__(self, torrent_path, use_fake_sink, save_path, algorithm,
            stream_length, buffer_size):

        super(VideoTorrentPlayer, self).__init__("video-torrent-player")

        self.torrent_path = torrent_path
        self.use_fake_sink = use_fake_sink
        self.save_path = save_path
        self.algorithm = algorithm
        self.stream_length = stream_length
        self.buffer_size = buffer_size
        
        self.download_rates = []
        self.upload_rates = []
        self.download_time = time()
        self.download_finished = False

        # Creating, configuring and linking GStreamer elements
        self.init_pipeline()

        # Creating BufferManager
        self.buffer_manager = BufferManager(self)

        # Adding torrent status checking thread
        gobject.timeout_add(1000, self.check_status)
예제 #2
0
class VideoTorrentPlayer(gst.Pipeline):
    """
    Provides a GStreamer pipeline for video playing from a torrent
    source.
    """

    def __init__(self, torrent_path, use_fake_sink, save_path, algorithm,
            stream_length, buffer_size):

        super(VideoTorrentPlayer, self).__init__("video-torrent-player")

        self.torrent_path = torrent_path
        self.use_fake_sink = use_fake_sink
        self.save_path = save_path
        self.algorithm = algorithm
        self.stream_length = stream_length
        self.buffer_size = buffer_size
        
        self.download_rates = []
        self.upload_rates = []
        self.download_time = time()
        self.download_finished = False

        # Creating, configuring and linking GStreamer elements
        self.init_pipeline()

        # Creating BufferManager
        self.buffer_manager = BufferManager(self)

        # Adding torrent status checking thread
        gobject.timeout_add(1000, self.check_status)

    def init_pipeline(self):
        # Creating elements
        self.src = gst.element_factory_make("btstreamsrc", "src")
        self.decoder = gst.element_factory_make("decodebin2", "decoder")
        # Creating sink elements (audio, video)
        self.create_sinks()

        # Configuring elements
        self.src.set_property("torrent", self.torrent_path)
        self.src.set_property("save_path", self.save_path)
        self.src.set_property("algorithm", self.algorithm)
        self.src.set_property("stream_length", self.stream_length)

        # Configuring playback buffer        
        self.decoder.set_property("use-buffering", True)
        self.decoder.set_property("low-percent", 5)
        self.decoder.set_property("max-size-bytes", 
            int(self.buffer_size * 1024 * 1024))

        # Configuring callbacks
        self.decoder.connect("new-decoded-pad", self.handle_decoded_pad)

        # Adding elements
        self.add(self.src, self.decoder, self.audio_sink, self.video_sink)

        # Linking elements
        gst.element_link_many(self.src, self.decoder)

    def handle_decoded_pad(self, demuxer, new_pad, is_last):
        structure_name = new_pad.get_caps()[0].get_name()
        if structure_name.startswith("audio"):
            new_pad.link(self.audio_sink.get_pad("sink"))

        elif structure_name.startswith("video"):
            new_pad.link(self.video_sink.get_pad("sink"))

    def create_sinks(self):
        if not self.use_fake_sink:
            self.audio_sink = AudioSink()
            self.video_sink = VideoSink()

        else:
            self.audio_sink = FakeSink("audio-sink")
            self.video_sink = FakeSink("video-sink")

    def check_status(self):
        download_progress = self.src.get_property("download_progress") * 100

        if download_progress < 100:
            download_rate = self.src.get_property("download_rate") / 1024
            self.download_rates.append(download_rate)

            pieces = self.src.get_property("pieces")
            num_pieces = self.src.get_property("num_pieces")

            logger.log("Download progress: %d%%" % download_progress)
            logger.log("Download rate: %d KiB/s" % download_rate)
            logger.log("Pieces: %s" % pieces)
            logger.log("Number of pieces: %s" % num_pieces)

        elif not self.download_finished:
            self.download_finished = True
            self.download_time = time() - self.download_time

            logger.log_event("Download finished.")

        upload_rate = self.src.get_property("upload_rate") / 1024
        self.upload_rates.append(upload_rate)

        logger.log("Upload rate: %d KiB/s" % upload_rate)

        peers = self.src.get_property("num_peers")
        seeds = self.src.get_property("num_seeds")
        connected_peers = self.src.get_property("num_connected_peers")
        connected_seeds = self.src.get_property("num_connected_seeds")
        num_uploads = self.src.get_property("num_uploads")
        distributed_copies = self.src.get_property("distributed_copies")
        next_announce = self.src.get_property("next_announce")

        logger.log("Connected peers (total): %d (%d)" % (connected_peers, peers))
        logger.log("Connected seeds (total): %d (%d)" % (connected_seeds, seeds))
        logger.log("Number of unchocked peers: %d" % num_uploads)
        logger.log("Distributed copies: %d" % distributed_copies)
        logger.log("Next annouce to tracker (s): %d" % next_announce)

        return True

    def close(self):
        self.set_state(gst.STATE_NULL)
        self.log()
        logger.close()

    def log(self):
        mean_download_rate = stats.avg(self.download_rates)
        std_download_rate = stats.std(self.download_rates)

        mean_upload_rate = stats.avg(self.upload_rates)
        std_upload_rate = stats.std(self.upload_rates)

        logger.log("--*--Torrent statistics--*--")
        logger.log("Download rate (KiB/s) - mean: %f" % mean_download_rate)
        logger.log("Download rate (KiB/s) - standard deviation: %f" % std_download_rate)
        logger.log("Upload rate (KiB/s) - mean: %f" % mean_upload_rate)
        logger.log("Upload rate (KiB/s) - standard deviation: %f" % std_upload_rate)

        logger.log_to_file("download_rate_mean, %f\r\n" % mean_download_rate)
        logger.log_to_file("download_rate_stdev, %f\r\n" % std_download_rate)
        logger.log_to_file("upload_rate_mean, %f\r\n" % mean_upload_rate)
        logger.log_to_file("upload_rate_stdev, %f\r\n" % std_upload_rate)

        if self.download_finished:
            logger.log("Download time (s): %d" % self.download_time)
            logger.log_to_file("download_time, %d\r\n" % self.download_time)
        else:
            logger.log_to_file("download_time, %d\r\n" % -1)

        self.buffer_manager.log()