Commit 790ca0a2 authored by Seb's avatar Seb
Browse files

Added quality field to transcode form. Created method of transcoding using...

Added quality field to transcode form. Created method of transcoding using different qualities for each media format
parent 5a809ce4
......@@ -10,7 +10,7 @@ from wagtail.wagtailadmin.forms import (BaseCollectionMemberForm,
collection_member_permission_formset_factory)
from wagtailvideos.fields import WagtailVideoField
from wagtailvideos.models import MediaFormats, Video
from wagtailvideos.models import MediaFormats, Video, VideoQuality
from wagtailvideos.permissions import \
permission_policy as video_permission_policy
......@@ -55,6 +55,7 @@ def get_video_form(model):
class VideoTranscodeAdminForm(forms.Form):
media_format = EnumField(MediaFormats)
quality = EnumField(VideoQuality)
def __init__(self, video, data=None, **kwargs):
super(VideoTranscodeAdminForm, self).__init__(data=data, **kwargs)
......@@ -62,7 +63,8 @@ class VideoTranscodeAdminForm(forms.Form):
def save(self):
media_format = self.cleaned_data['media_format']
self.video.do_transcode(media_format)
quality = self.cleaned_data['quality']
self.video.do_transcode(media_format, quality)
GroupVideoPermissionFormSet = collection_member_permission_formset_factory(
......
# -*- coding: utf-8 -*-
# Generated by Django 1.9.7 on 2016-08-01 04:35
from __future__ import unicode_literals
from django.db import migrations
import enumchoicefield.fields
import wagtailvideos.models
class Migration(migrations.Migration):
dependencies = [
('wagtailvideos', '0008_auto_20160728_1523'),
]
operations = [
migrations.AddField(
model_name='videotranscode',
name='quality',
field=enumchoicefield.fields.EnumChoiceField(default=wagtailvideos.models.VideoQuality(1), enum_class=wagtailvideos.models.VideoQuality, max_length=7),
),
]
......@@ -31,11 +31,39 @@ from wagtail.wagtailsearch.queryset import SearchableQuerySetMixin
logger = logging.getLogger(__name__)
class VideoQuality(ChoiceEnum):
default = 'Default'
lowest = 'Low'
highest = 'High'
class MediaFormats(ChoiceEnum):
webm = 'VP8 and Vorbis in WebM'
mp4 = 'H.264 and MP3 in Mp4'
ogg = 'Theora and Voris in Ogg'
def get_quality_param(self, quality):
if self is MediaFormats.webm:
if quality is VideoQuality.lowest:
return '50'
elif quality is VideoQuality.highest:
return '4'
return '22'
elif self is MediaFormats.mp4:
if quality is VideoQuality.lowest:
return '28'
if quality is VideoQuality.highest:
return '18'
return '24'
elif self is MediaFormats.ogg:
if quality is VideoQuality.lowest:
return '5'
if quality is VideoQuality.highest:
return '9'
return '7'
class VideoQuerySet(SearchableQuerySetMixin, models.QuerySet):
pass
......@@ -200,13 +228,14 @@ class AbstractVideo(CollectionMember, TagSearchable):
except Transcode.DoesNotExist:
return self.do_transcode(media_format)
def do_transcode(self, media_format, force=False):
def do_transcode(self, media_format, quality):
transcode, created = self.transcodes.get_or_create(
media_format=media_format,
)
if transcode.processing is False:
transcode.processing = True
transcode.error_messages = ''
transcode.quality = quality
transcode.save(update_fields=['processing', 'error_message']) # Lock the transcode model
TranscodingThread(transcode).start()
else:
......@@ -242,12 +271,13 @@ class TranscodingThread(threading.Thread):
output_file = os.path.join(output_dir, transcode_name)
FNULL = open(os.devnull, 'r')
quality_param = media_format.get_quality_param(self.transcode.quality)
args = ['ffmpeg', '-hide_banner', '-i', input_file]
try:
if media_format is MediaFormats.ogg:
subprocess.check_output(args + [
'-codec:v', 'libtheora',
'-qscale:v', '7',
'-qscale:v', quality_param,
'-codec:a', 'libvorbis',
'-qscale:a', '5',
output_file,
......@@ -256,15 +286,14 @@ class TranscodingThread(threading.Thread):
subprocess.check_output(args + [
'-codec:v', 'libx264',
'-preset', 'slow', # TODO Checkout other presets
'-crf', '22',
'-crf', quality_param,
'-codec:a', 'copy',
output_file,
], stdin=FNULL, stderr=subprocess.STDOUT)
elif media_format is MediaFormats.webm:
subprocess.check_output(args + [
'-codec:v', 'libvpx',
'-crf', '10',
'-b:v', '1M',
'-crf', quality_param,
'-codec:a', 'libvorbis',
output_file,
], stdin=FNULL, stderr=subprocess.STDOUT)
......@@ -286,6 +315,7 @@ def video_delete(sender, instance, **kwargs):
instance.thumbnail.delete(False)
instance.file.delete(False)
# Fields that need the actual video file to create
@receiver(post_save, sender=Video)
def video_saved(sender, instance, **kwargs):
......@@ -298,11 +328,13 @@ def video_saved(sender, instance, **kwargs):
instance.save()
del instance._from_signal
class AbstractVideoTranscode(models.Model):
media_format = EnumChoiceField(MediaFormats)
quality = EnumChoiceField(VideoQuality, default=VideoQuality.default)
processing = models.BooleanField(default=False)
file = models.FileField(null=True, blank=True,
verbose_name=_('file'), upload_to=get_upload_to)
file = models.FileField(null=True, blank=True, verbose_name=_('file'),
upload_to=get_upload_to)
error_message = models.TextField(blank=True)
@property
......@@ -326,6 +358,7 @@ class VideoTranscode(AbstractVideoTranscode):
('video', 'media_format')
)
# Delete files when model is deleted
@receiver(pre_delete, sender=VideoTranscode)
def transcode_delete(sender, instance, **kwargs):
......
......@@ -52,13 +52,13 @@
<h2 class="label">{% trans "Video preview" %}</h2>
{% video video controls style=max-width:100% %}
<h3 class="label">Transcodes</h3>
<p>If you wish to generate HTML5 compliant transcodes use the form below. This may take a while dependung in the length of the video.</p>
<p>If you wish to generate HTML5 compliant transcodes use the form below. This may take a while depending in the length of the video.</p>
{% if transcodes %}
<h3 class="label">Available Transcodes</h3>
<ul>
{% for transcode in transcodes %}
<li>
{{ transcode.media_format }}
{{ transcode.media_format }} ({{ transcode.quality }} quality)
{% if transcode.processing %} <span class='processing'>(Processing... hold tight) </span>{% endif %}
{% if transcode.error_message %}
<span class='transcode-error'>ERROR:</span>
......@@ -75,6 +75,7 @@
<ul class="fields">
{% csrf_token %}
{% include "wagtailadmin/shared/field_as_li.html" with field=transcode_form.media_format %}
{% include "wagtailadmin/shared/field_as_li.html" with field=transcode_form.quality %}
<li>
<input class="button" type='submit' value="Start" />
</li>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment