Reputation: 471
I am displaying my videos in my django site. I want to display those video like thumbnails, but I don't know how to create thumbnails for my videos. I have stored my videos through admin module. here is my code
models.py
class Video(models.Model):
title = models.CharField(max_length=200, null=True, blank=True)
video = models.FileField(upload_to='static/gallery/videos',
null=False,
help_text=_("video file")
)
admin.py
from django.contrib import admin
from .models import Video
admin.site.register(Video)
Any one help me for how to store my video thumbnails format in db or how to display my retrieved videos in thumbnail format.
Thanks in advance
Upvotes: 3
Views: 7065
Reputation: 583
Here is an example of generating a thumbnail. You can adjust the code to your needs for a Django project.
I am using ffmpeg-python: Python bindings for FFmpeg
import ffmpeg
from django.core.files.base import ContentFile
from django.core.files.temp import NamedTemporaryFile
with NamedTemporaryFile() as temp_video_file:
# user_video is a django model instance with video and thumbnail FileFields
in_memory_file = user_video.video
if in_memory_file.multiple_chunks():
for chunk in in_memory_file.chunks():
temp_video_file.write(chunk)
else:
temp_video_file.write(in_memory_file.read())
try:
probe = ffmpeg.probe(temp_video_file.name)
time = float(probe["streams"][0]["duration"]) // 2
width = probe["streams"][0]["width"]
with NamedTemporaryFile(suffix=".jpg") as temp_thumbnail_file:
(
ffmpeg.input(temp_video_file.name, ss=time)
.filter("scale", width, -1)
.output(temp_thumbnail_file.name, vframes=1)
.overwrite_output()
.run(capture_stdout=True, capture_stderr=True)
)
except ffmpeg.Error as e:
# do whatever you want with the error
error = e.stderr.decode()
else:
# you can also just return the thumbnail e.g
# return ContentFile('name_you_like.jpg', temp_thumbnail_file.read())
user_video.thumbnail.save(
Path(temp_thumbnail_file.name).name,
ContentFile(temp_thumbnail_file.read()),
save=True,
)
Upvotes: 1
Reputation: 31
1)install opencv-python 2)check if file is video or image 3)i couldnt figure out to videocapture from memory so write the file to disk then load using cv2.videocapture 4)take first frame and write to disk 5)again load image from disk and save it in database 6)delete the temporary files in disk
import mimetypes
import cv2
from django.core.files import File
from django.core.files.storage import default_storage
from django.core.files.base import ContentFile
from pathlib import Path
new_story=Story(user=user, file=file)
file_type, t =mimetypes.guess_type(str(file))
if file_type.split('/')[0] == "image":
new_story.save()
return Storymutation(story=new_story)
path = default_storage.save('video.mp4', ContentFile(file.read()))
vidcap = cv2.VideoCapture(f"./media/{path}")
success,image = vidcap.read()
cv2.imwrite(f"./media/{path}.jpeg", image)
thumbnail = default_storage.open(f"{path}.jpeg")
new_story.thumbnail=thumbnail
new_story.save()
thumbnail.close()
del image, vidcap
default_storage.delete(path)
default_storage.delete(f"{path}.jpeg")
return Storymutation(story=new_story)
Upvotes: 1
Reputation: 4251
You can add a nullable file field to store thumbnail and fill it manually in save
method or using a model save signal.
You can use answers to these questions to find out how to generate those thumbnails:
https://stackoverflow.com/a/1843043/1823497
https://stackoverflow.com/a/27565893/1823497
Since generating thumbnails can be a time consuming job, i recommend to use a celery task to do it in background without blocking your webserver.
Upvotes: 3