Search code examples
djangodjango-rest-frameworkthumbnailsdjango-signalsmoviepy

Django Signals - How to save the instance


I am using Django Rest Framework to upload videos. Now I wanted to add thumbnails to my video files. Whenever a Video object is saved, I wanted to create a thumbnail and set its thumbnail field.

My Video model looks like this:

class Video(models.Model):
    created = models.DateTimeField(auto_now_add=True)
    text = models.CharField(max_length=100, blank=True)
    video = models.FileField(upload_to='Videos/',blank=True)
    thumbnail = models.ImageField(upload_to = 'Images/', blank = True)

My signal handler looks like this:

from moviepy.video.io.VideoFileClip import VideoFileClip
from posts.models import Video
from django.db.models.signals import post_save
from django.dispatch import receiver
from settingsFolderOfProject.settings import MEDIA_ROOT
import os

# when save() of Video is done, create_thumbnail_from_video() is called
@receiver(post_save, sender=Video)
def create_thumbnail_from_video(sender, instance, created, **kwargs):
    if created:
        # create the clip using moviepy's VideoFileClip class
        clip = VideoFileClip(os.path.join(MEDIA_ROOT, instance.video.name))
        # create the frame at 1st second and set it to instance's thumbnail field
        instance.thumbnail = clip.save_frame(os.path.join(MEDIA_ROOT, 'Images/thumbnail.jpg'),t='00:00:01') 
        # save the instance 
        instance.save()       # <--- I think this op does not work properly

What I have to change? The thumbnail file gets created in the folder as expected but Django does not set the thumbnail field of my Video model instance. The thumbnail field of the created Video instance is still set to null.


Solution

  • clip.save_frame() doesn't return anything. Instead do

    path = os.path.join(MEDIA_ROOT, 'Images/thumbnail.jpg')
    clip.save_frame(path,t='00:00:01') 
    instance.thumbnail = path
    instance.save()
    

    Note: Haven't tested yet. Comment if problem still persists. Thnx...