示例#1
0
def enqueue(func, *args, **kwargs):
    if get_setting('redis', 'eager'):
        func(*args, **kwargs)
    else:
        q = Queue(connection=redis_conn,
                  name=get_queue_name(),
                  default_timeout=get_setting('redis', 'timeout'))
        q.enqueue(func, *args, **kwargs)
示例#2
0
def convert_video(infile, outfile, codec, quality, original_bitrate, original_width, original_height):
    if not codec in constants.VIDEO_CODECS.keys():
        raise AttributeError("Parameter 'codec' must be in {0}!".format(constants.VIDEO_CODECS.keys))
    commands = get_setting('ffmpeg', 'convert_settings', 'commands', codec)

    if not os.path.exists(os.path.dirname(outfile)):
        os.makedirs(os.path.dirname(outfile))

    tmp_dir = tempfile.mkdtemp()

    settings = get_setting('ffmpeg', 'convert_settings', quality)
    for cmd in commands:
        if quality == 'original':
            video_bitrate = min(original_bitrate, int(settings.get('video_bitrate').replace('k', '')))
            video_max_bitrate = video_bitrate * 2
            video_bufsize = video_max_bitrate
            cmd = cmd.format(
                ffmpeg=get_setting('ffmpeg', 'binary'),
                infile=infile,
                outfile=outfile,
                video_bitrate="{0}k".format(int(video_bitrate)),
                video_max_bitrate="{0}k".format(int(video_max_bitrate)),
                video_bufsize="{0}k".format(int(video_bufsize)),
                video_size=settings.get('video_size').format(
                    original_width=original_width, original_height=original_height
                ),
            )
        else:
            cmd = cmd.format(
                ffmpeg=get_setting('ffmpeg', 'binary'),
                infile=infile,
                outfile=outfile,
                video_bitrate=settings.get('video_bitrate'),
                video_max_bitrate=settings.get('video_max_bitrate'),
                video_bufsize=settings.get('video_bufsize'),
                video_size=settings.get('video_size'),
            )

        try:
            subprocess.check_output(cmd.split(), stderr=subprocess.PIPE, cwd=tmp_dir)
        except AttributeError:
            # fallback for Python 2.6
            subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, cwd=tmp_dir).communicate()
    shutil.rmtree(tmp_dir, ignore_errors=True)
    return os.path.exists(outfile)
示例#3
0
def _get_image_paths(infile, n):
    basename, _ = os.path.splitext(os.path.basename(infile))
    path_rel = os.path.join(get_setting('screens_to'),
                            "{0}.{1}.jpg".format(basename, n))

    path_abs = os.path.join(
        settings.MEDIA_ROOT,
        path_rel,
    )

    return path_rel, path_abs
示例#4
0
def video_info(infile):
    cmd = "{ffmpeg} -i {infile} -y -f rawvideo -vframes 1 /dev/null".format(
        ffmpeg=get_setting('ffmpeg', "binary"),
        infile=infile,
    )

    try:
        result = subprocess.check_output(cmd.split(), stderr=subprocess.STDOUT)
    except AttributeError:
        # fallback for Python 2.6
        result = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()[0]
    except subprocess.CalledProcessError, e:
        result = str(e.output)
示例#5
0
def _get_image_paths(infile, n):
    basename, _ = os.path.splitext(os.path.basename(infile))
    path_rel = os.path.join(
        get_setting('screens_to'),
        "{0}.{1}.jpg".format(basename, n)
    )

    path_abs = os.path.join(
        settings.MEDIA_ROOT,
        path_rel,
    )

    return path_rel, path_abs
示例#6
0
def create_screen_image(infile, outfile, second):
    cmd = "{ffmpeg} -itsoffset -{second} -i {infile} -y -vcodec mjpeg -vframes 1 -an -f rawvideo {outfile}".format(
        ffmpeg=get_setting('ffmpeg', "binary"),
        infile=infile,
        second=second,
        outfile=outfile,
    )

    if not os.path.exists(os.path.dirname(outfile)):
        os.makedirs(os.path.dirname(outfile))

    try:
        subprocess.check_output(cmd.split(), stderr=subprocess.PIPE)
    except AttributeError:
        # fallback for Python 2.6
        subprocess.Popen(cmd.split(), stdout=subprocess.PIPE).communicate()
    except subprocess.CalledProcessError, e:
        print "CalledProcessError:"
        print e
        return False
示例#7
0
def _get_video_paths(infile, codec):
    if not codec in constants.VIDEO_CODECS.keys():
        raise AttributeError("Parameter 'codec' must be in {0}!".format(constants.VIDEO_CODECS.keys))
    ext = constants.VIDEO_CODECS.get(codec)

    basename, _ = os.path.splitext(os.path.basename(infile))
    paths = {}
    for quality in constants.VIDEO_QUALITIES + ('original',):
        rel = os.path.join(
            get_setting('convert_to'),
            "{0}.{1}.{2}.{3}".format(basename, codec, quality, ext)
        )
        paths[quality] = {
            'relative': rel,
            'absolute': os.path.join(
                settings.MEDIA_ROOT,
                rel,
            ),
        }
    return paths
示例#8
0
def _get_video_paths(infile, codec):
    if not codec in constants.VIDEO_CODECS.keys():
        raise AttributeError("Parameter 'codec' must be in {0}!".format(
            constants.VIDEO_CODECS.keys))
    ext = constants.VIDEO_CODECS.get(codec)

    basename, _ = os.path.splitext(os.path.basename(infile))
    paths = {}
    for quality in constants.VIDEO_QUALITIES + ('original', ):
        rel = os.path.join(
            get_setting('convert_to'),
            "{0}.{1}.{2}.{3}".format(basename, codec, quality, ext))
        paths[quality] = {
            'relative': rel,
            'absolute': os.path.join(
                settings.MEDIA_ROOT,
                rel,
            ),
        }
    return paths
示例#9
0
class ConvertedVideo(models.Model):
    owner = models.ForeignKey(User, null=True, blank=True)
    video = models.FileField(upload_to=get_setting('convert_to'))
    original = models.ForeignKey('WebVideo', related_name='converted')
    codec = models.CharField(max_length=20,
                             choices=constants.VIDEO_CODEC_CHOICES)
    quality = models.CharField(max_length=20,
                               choices=constants.VIDEO_QUALITY_CHOICES)
    filesize = models.IntegerField(default=0)
    duration = models.FloatField(default=0.0,
                                 verbose_name=_(u"Duration in seconds"))
    width = models.IntegerField(default=0)
    height = models.IntegerField(default=0)
    bitrate = models.FloatField(default=0.0,
                                verbose_name=_(u"Bitrate in kb/s"))
    framerate = models.FloatField(default=29.92)

    status = models.SmallIntegerField(choices=constants.VIDEO_STATE_CHOICES,
                                      default=constants.VIDEO_STATE_PENDING,
                                      editable=False)

    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):
        self.owner = self.original.owner
        super(ConvertedVideo, self).save(force_insert, force_update, using,
                                         update_fields)

    class Meta:
        unique_together = (
            'original',
            'codec',
            'quality',
        )

    def __unicode__(self):
        return "{0} ({1}, {2})".format(self.video, self.codec, self.quality)
示例#10
0
class VideoScreen(models.Model):
    owner = models.ForeignKey(User, null=True, blank=True)
    video = models.ForeignKey('WebVideo', related_name='screen')
    image = models.ImageField(upload_to=get_setting('screens_to'))
    num = models.IntegerField(max_length=2)

    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):
        self.owner = self.video.owner
        super(VideoScreen, self).save(force_insert, force_update, using,
                                      update_fields)

    class Meta:
        unique_together = (
            'video',
            'num',
        )

    def __unicode__(self):
        return "{0}, Screen {1}".format(self.video.video, self.num)
示例#11
0
        'height',
        'bitrate',
        'framerate',
    )
    readonly_fields = (
        'admin_video',
        'original',
        'admin_filesize',
        'codec',
        'quality',
        'duration',
        'width',
        'height',
        'bitrate',
        'framerate',
    )
    list_filter = ('codec', 'quality')

    admin_thumb = admin_thumb_helper_video(width=50, height=30)
    admin_video = admin_video_helper()
    admin_filesize = admin_filesize_helper()

    def has_add_permission(self, request):
        return False


if get_setting('use_admin'):
    admin.site.register(WebVideo, WebVideoAdmin)
    admin.site.register(VideoScreen, VideoScreenAdmin)
    admin.site.register(ConvertedVideo, ConvertedVideoAdmin)
示例#12
0
def enqueue(func, *args, **kwargs):
    if get_setting('redis', 'eager'):
        func(*args, **kwargs)
    else:
        q = Queue(connection=redis_conn, name=get_queue_name(), default_timeout=get_setting('redis', 'timeout'))
        q.enqueue(func, *args, **kwargs)
示例#13
0
# coding=utf-8
from django_webvideo.settings import get_setting, get_queue_name
from rq import Queue
from redis import Redis


redis_conn = Redis(
    host=get_setting('redis', 'connection', 'host'),
    db=get_setting('redis', 'connection', 'db'),
    port=get_setting('redis', 'connection', 'port'),
)


def enqueue(func, *args, **kwargs):
    if get_setting('redis', 'eager'):
        func(*args, **kwargs)
    else:
        q = Queue(connection=redis_conn, name=get_queue_name(), default_timeout=get_setting('redis', 'timeout'))
        q.enqueue(func, *args, **kwargs)
示例#14
0
# coding=utf-8
from django_webvideo.settings import get_setting, get_queue_name
from rq import Queue
from redis import Redis

redis_conn = Redis(
    host=get_setting('redis', 'connection', 'host'),
    db=get_setting('redis', 'connection', 'db'),
    port=get_setting('redis', 'connection', 'port'),
)


def enqueue(func, *args, **kwargs):
    if get_setting('redis', 'eager'):
        func(*args, **kwargs)
    else:
        q = Queue(connection=redis_conn,
                  name=get_queue_name(),
                  default_timeout=get_setting('redis', 'timeout'))
        q.enqueue(func, *args, **kwargs)
示例#15
0
class WebVideo(models.Model):
    owner = models.ForeignKey(User, null=True, blank=True, editable=False)
    video = models.FileField(upload_to=get_setting('upload_to'))
    filesize = models.IntegerField(default=0, editable=False)
    duration = models.FloatField(default=0.0,
                                 verbose_name=_(u"Duration in seconds"),
                                 editable=False)
    width = models.IntegerField(default=0, editable=False)
    height = models.IntegerField(default=0, editable=False)
    bitrate = models.FloatField(default=0.0,
                                verbose_name=_(u"Bitrate in kb/s"),
                                editable=False)
    framerate = models.FloatField(default=29.92, editable=False)

    codecs = models.CharField(max_length=255,
                              blank=True,
                              null=True,
                              editable=True)
    qualities = models.CharField(max_length=255,
                                 blank=True,
                                 null=True,
                                 editable=True)

    @property
    def status(self):
        if self.converted.all().count() == 0:
            return constants.VIDEO_STATE_PENDING
        else:
            return constants.VIDEO_STATE_SUCCESS

    def __unicode__(self):
        return self.video.url

    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):
        old_video = None
        if self.pk is not None:
            try:
                old_video = WebVideo.objects.get(pk=self.pk).video
            except WebVideo.DoesNotExist:
                pass
        if old_video != self.video:
            self.converted.all().delete()
            self.screen.all().delete()
            super(WebVideo, self).save(force_insert, force_update, using,
                                       update_fields)
            _set_meta(self)
            self.create_screen_images()
            self.convert()
        super(WebVideo, self).save(force_insert, force_update, using,
                                   update_fields)

    def get_screen(self, num=1):
        try:
            return self.screen.get(video=self, num=num)
        except VideoScreen.DoesNotExist:
            return None

    def get_video(self, codec, quality):
        try:
            return self.converted.get(original=self,
                                      codec=codec,
                                      quality=quality)
        except ConvertedVideo.DoesNotExist:
            return None

    def convert(self):
        if self.status != constants.VIDEO_STATE_PENDING:
            return
        for codec in self.codecs.split(','):
            for quality in self.qualities.split(','):
                #minrate = constants.VIDEO_QUALITY_MIN_BITRATES[quality]
                #if self.bitrate > 0 and self.bitrate >= minrate:
                queue.enqueue(_convert_single, self.pk, codec, quality)
            #queue.enqueue(_convert_single, self.pk, codec, 'original')

    def convert_single(self, codec, quality):
        paths = _get_video_paths(self.video.path, codec)[quality]

        conv = ConvertedVideo(original=self,
                              codec=codec,
                              quality=quality,
                              owner=self.owner)

        if convert_video(self.video.path, paths.get('absolute'), codec,
                         quality, self.bitrate, self.width, self.height):
            # get object from db to prevent "no-save" bug in rq
            conv.video.name = paths.get('relative')
            conv.status = constants.VIDEO_STATE_SUCCESS
            _set_meta(conv)
            conv.save()
            return True
        else:
            conv.status = constants.VIDEO_STATE_ERROR
            conv.save()
            return False

    def create_screen_images(self):
        if self.duration == 0:
            return

        dur = self.duration

        for num in range(1, constants.NUM_SCREENS + 1):
            relative, absolute = _get_image_paths(self.video.path, num)
            if num == 1:
                frame = round(min(dur * 0.5, 0.5), 2)
            else:
                frame = round(dur / constants.NUM_SCREENS * (num * 0.9), 2)
            if create_screen_image(self.video.path, absolute, frame):
                VideoScreen(video=self,
                            image=relative,
                            num=num,
                            owner=self.owner).save()

    def converted_list_admin(self):
        return [
            "{0}, {1}".format(c.codec, c.quality)
            for c in self.converted.all()
        ]

    converted_list_admin.short_description = _('Converted variants')