Implement video view page
This commit is contained in:
24
static/js/video.js
Normal file
24
static/js/video.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
function init() {
|
||||||
|
|
||||||
|
var hash = document.location.hash;
|
||||||
|
var res = hash.match(/t=([0-9]+)/);
|
||||||
|
if (res) {
|
||||||
|
var vids = document.getElementsByTagName('video');
|
||||||
|
// only first video
|
||||||
|
var vid = vids[0];
|
||||||
|
vid.currentTime = res[1];
|
||||||
|
vid.autoplay = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init();
|
||||||
|
|
||||||
|
function vidTimeInUrl(el) {
|
||||||
|
var vids = document.getElementsByTagName('video');
|
||||||
|
// only first video
|
||||||
|
var vid = vids[0];
|
||||||
|
var currentTime = vid.currentTime;
|
||||||
|
var href = el.href + "#t=" + parseInt(currentTime);
|
||||||
|
el.href = href;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -58,6 +58,9 @@ class Video(models.Model):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
indexes = [models.Index(fields=['slug']), models.Index(fields=['created_at'])]
|
||||||
|
|
||||||
class Transcoding(models.Model):
|
class Transcoding(models.Model):
|
||||||
id = models.AutoField(primary_key=True)
|
id = models.AutoField(primary_key=True)
|
||||||
video = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='transcodings')
|
video = models.ForeignKey(Video, on_delete=models.CASCADE, related_name='transcodings')
|
||||||
|
|||||||
@@ -66,6 +66,12 @@ TEMPLATES = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
'BACKEND': 'django.template.backends.jinja2.Jinja2',
|
||||||
|
'DIRS': [os.path.join(BASE_DIR, 'videodinges', 'templates')],
|
||||||
|
'APP_DIRS': False,
|
||||||
|
'OPTIONS': {},
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = 'videodinges.wsgi.application'
|
WSGI_APPLICATION = 'videodinges.wsgi.application'
|
||||||
|
|||||||
31
videodinges/templates/video.html.j2
Normal file
31
videodinges/templates/video.html.j2
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
{# <link rel="stylesheet" href="style.css" type="text/css" media="screen" /> #}
|
||||||
|
{% if og_image %}
|
||||||
|
<meta property="og:image" content="{{og_image}}" />
|
||||||
|
{% endif %}
|
||||||
|
<title>{{ title }}</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
<video width="{{ width }}" height="{{ height }}" {% if poster %}poster="{{ poster }}" {% endif %}controls="controls">
|
||||||
|
{% for source in sources %}
|
||||||
|
<source src="{{ source.src }}" type='{{ source.type }}' />
|
||||||
|
{% endfor %}
|
||||||
|
You need a browser that understands HTML5 video and supports {% for i in used_codecs %}{{ i }}{% if not loop.last %} or {% endif %}{% endfor %} codecs.
|
||||||
|
</video><br />
|
||||||
|
<p>
|
||||||
|
{% for quality in qualities %}
|
||||||
|
<a href="{{ slug }}.html?quality={{ quality }}" onclick="vidTimeInUrl(this);">{{ quality }} versie</a>{% if not loop.last %} | {% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{ description|safe }}
|
||||||
|
</p>
|
||||||
|
<div id="commenter-container" data-object-id="welmers-video-{{ slug }}">
|
||||||
|
<div class="commenter-count-container"><span class="commenter-count">0</span> comments total</div>
|
||||||
|
</div>
|
||||||
|
<script data-container="commenter-container" src="//www.welmers.net/commenter/js/commenter.js" type="text/javascript"></script>
|
||||||
|
<script src="/static/js/video.js" type="text/javascript"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -16,10 +16,11 @@ Including another URLconf
|
|||||||
from django.conf.urls import url
|
from django.conf.urls import url
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from . import testviews
|
from . import testviews, views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^admin/', admin.site.urls),
|
url(r'^admin/', admin.site.urls),
|
||||||
|
url(r'^(?P<slug>[\w-]+).html', views.video)
|
||||||
]
|
]
|
||||||
|
|
||||||
for i in testviews.__all__:
|
for i in testviews.__all__:
|
||||||
|
|||||||
66
videodinges/views.py
Normal file
66
videodinges/views.py
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
from collections import defaultdict
|
||||||
|
from typing import List, Dict, Any
|
||||||
|
|
||||||
|
from django.http import HttpResponse, HttpRequest, Http404
|
||||||
|
from django.shortcuts import render
|
||||||
|
from . import models
|
||||||
|
|
||||||
|
def video(request: HttpRequest, slug: str) -> HttpResponse:
|
||||||
|
try:
|
||||||
|
video = models.Video.objects.get(slug=slug)
|
||||||
|
except models.Video.DoesNotExist:
|
||||||
|
raise Http404('Video not found')
|
||||||
|
|
||||||
|
template_data = dict(
|
||||||
|
og_image=video.og_image.file.url if video.og_image else None,
|
||||||
|
title=video.title,
|
||||||
|
poster=video.poster.file.url if video.poster else None,
|
||||||
|
description=video.description,
|
||||||
|
slug=video.slug
|
||||||
|
)
|
||||||
|
|
||||||
|
qualities = _get_qualities(video)
|
||||||
|
try:
|
||||||
|
quality = qualities[request.GET['quality']]
|
||||||
|
except:
|
||||||
|
quality = next(iter(qualities.values()))
|
||||||
|
|
||||||
|
template_data.update(
|
||||||
|
width=quality[0].quality_obj.width,
|
||||||
|
height=quality[0].quality_obj.height,
|
||||||
|
)
|
||||||
|
|
||||||
|
template_data['sources'] = [
|
||||||
|
{
|
||||||
|
'src': _url_for(transcoding),
|
||||||
|
'type': transcoding.type,
|
||||||
|
}
|
||||||
|
for transcoding in quality ]
|
||||||
|
|
||||||
|
template_data['used_codecs'] = [
|
||||||
|
models.get_short_name_of_transcoding_type(transcoding.type)
|
||||||
|
for transcoding in quality
|
||||||
|
]
|
||||||
|
|
||||||
|
template_data['qualities'] = qualities.keys()
|
||||||
|
|
||||||
|
return render(request, 'video.html.j2', template_data, using='jinja2')
|
||||||
|
|
||||||
|
def _get_dict_from_models_with_fields(model, *fields: str) -> Dict[str, Any]:
|
||||||
|
ret = {}
|
||||||
|
for field in fields:
|
||||||
|
ret[field] = model.__dict__[field]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def _get_qualities(video: models.Video) -> Dict[str, List[models.Transcoding]]:
|
||||||
|
transcodings: List[models.Transcoding] = video.transcodings.order_by('quality').all()
|
||||||
|
qualities = defaultdict(list)
|
||||||
|
for transcoding in transcodings:
|
||||||
|
qualities[transcoding.quality_obj.name].append(transcoding)
|
||||||
|
return qualities
|
||||||
|
|
||||||
|
def _url_for(transcoding: models.Transcoding) -> str:
|
||||||
|
if transcoding.url:
|
||||||
|
return transcoding.url
|
||||||
|
elif transcoding.upload:
|
||||||
|
return transcoding.upload.file.url
|
||||||
Reference in New Issue
Block a user