我正在使用信号来更改上载的文件,并执行一些过程将.mkv | mp4文件转换为.m3u8和.ts文件,但是当我使用在信号中创建的新.m3u8文件保存实例时, instance.save方法再次调用该信号,这会引发错误。
代码示例:
@receiver(post_save, sender=Lecture)
def handle_video_upload(sender, instance, created, **kwargs):
# check if a new video has uploaded
file_has_changed = instance.tracker.has_changed('file')
if created or file_has_changed and instance.file_type == "V":
# .../ process to convert video into a .m3u8 file...
# open the m3u8 created file and change the original (mp4, mkv...) file for the m3u8
with open(m3u8_absolute_path, "r") as file_object:
file_m3u8 = File(name=m3u8_absolute_path, file=file_object)
instance.file.save(m3u8_filename, file_m3u8) # this call this signal again and raise a error
文件字段为:file = models.FileField()
完整代码:
import subprocess
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.core.files import File
from pathlib import Path
from .models import Lecture
@receiver(post_save, sender=Lecture)
def handle_video_upload(sender, instance, created, **kwargs):
# check if the file field has changed
file_has_changed = instance.tracker.has_changed('file')
# the process run when:
# the file_type is a video (setted as "V"), and:
# - the instance is created
# - the video is changed (i.e, reuploaded)
if created or file_has_changed and instance.file_type == "V":
instance_absolute_path = Path(instance.file.path)
m3u8_absolute_path = instance_absolute_path.with_suffix(".m3u8")
m3u8_filename = m3u8_absolute_path.name
# use shell commands to create HLS .m3u8 file
# and delete the original video file
subprocess.run([
"ffmpeg",
"-i",
instance_absolute_path,
"-f",
"hls",
m3u8_absolute_path
])
subprocess.run(["rm", instance_absolute_path])
# update the file with the new .m3u8 file
with open(m3u8_absolute_path, "r") as file_object:
file_m3u8 = File(name=m3u8_absolute_path, file=file_object)
instance.file.save(m3u8_filename, file_m3u8)
模型的相关代码:
class Lecture(models.Model):
FILE_TYPE_CHOICES = (("V", "Video"), ("P", "PDF"))
file = models.FileField()
file_type = models.CharField(
max_length=1,
choices=FILE_TYPE_CHOICES,
default="V")
tracker = FieldTracker()
该网站中的错误:
FileNotFoundError at /admin/lectures/lecture/add/
[Errno 2] No such file or directory: '/home/marcos/geeknoon/geeknoon_server/local/media/media/lectures/second/2020-04-04_16-11-20_8bbOfdb.m3u8