mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-10-06 22:32:41 +07:00
chapters
This commit is contained in:
committed by
Yiannis Christodoulou
parent
8f45afc1fe
commit
32f61cf566
@@ -12,40 +12,14 @@ class VideoChapterData(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ['media']
|
unique_together = ['media']
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
from .. import tasks
|
|
||||||
|
|
||||||
is_new = self.pk is None
|
|
||||||
if is_new or (not is_new and self._check_data_changed()):
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
tasks.produce_video_chapters.delay(self.pk)
|
|
||||||
else:
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
|
|
||||||
def _check_data_changed(self):
|
|
||||||
if self.pk:
|
|
||||||
old_instance = VideoChapterData.objects.get(pk=self.pk)
|
|
||||||
return old_instance.data != self.data
|
|
||||||
return False
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def chapter_data(self):
|
def chapter_data(self):
|
||||||
# ensure response is consistent
|
# ensure response is consistent
|
||||||
data = []
|
data = []
|
||||||
for item in self.data:
|
if self.data and isinstance(self.data, list):
|
||||||
if item.get("start") and item.get("title"):
|
for item in self.data:
|
||||||
thumbnail = item.get("thumbnail")
|
if item.get("startTime") and item.get("endTime") and item.get("text"):
|
||||||
if thumbnail:
|
data.append(item)
|
||||||
thumbnail = helpers.url_from_path(thumbnail)
|
|
||||||
else:
|
|
||||||
thumbnail = "static/images/chapter_default.jpg"
|
|
||||||
data.append(
|
|
||||||
{
|
|
||||||
"start": item.get("start"),
|
|
||||||
"title": item.get("title"),
|
|
||||||
"thumbnail": thumbnail,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -950,45 +950,6 @@ def update_encoding_size(encoding_id):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@task(name="produce_video_chapters", queue="short_tasks")
|
|
||||||
def produce_video_chapters(chapter_id):
|
|
||||||
# this is not used
|
|
||||||
return False
|
|
||||||
chapter_object = VideoChapterData.objects.filter(id=chapter_id).first()
|
|
||||||
if not chapter_object:
|
|
||||||
return False
|
|
||||||
|
|
||||||
media = chapter_object.media
|
|
||||||
video_path = media.media_file.path
|
|
||||||
output_folder = media.video_chapters_folder
|
|
||||||
|
|
||||||
chapters = chapter_object.data
|
|
||||||
|
|
||||||
width = 336
|
|
||||||
height = 188
|
|
||||||
|
|
||||||
if not os.path.exists(output_folder):
|
|
||||||
os.makedirs(output_folder)
|
|
||||||
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for i, chapter in enumerate(chapters):
|
|
||||||
timestamp = chapter["start"]
|
|
||||||
title = chapter["title"]
|
|
||||||
|
|
||||||
output_filename = f"thumbnail_{i:02d}.jpg" # noqa
|
|
||||||
output_path = os.path.join(output_folder, output_filename)
|
|
||||||
|
|
||||||
command = [settings.FFMPEG_COMMAND, "-y", "-ss", str(timestamp), "-i", video_path, "-vframes", "1", "-q:v", "2", "-s", f"{width}x{height}", output_path]
|
|
||||||
ret = run_command(command) # noqa
|
|
||||||
if os.path.exists(output_path) and get_file_type(output_path) == "image":
|
|
||||||
results.append({"start": timestamp, "title": title, "thumbnail": output_path})
|
|
||||||
|
|
||||||
chapter_object.data = results
|
|
||||||
chapter_object.save(update_fields=["data"])
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
@task(name="post_trim_action", queue="short_tasks", soft_time_limit=600)
|
@task(name="post_trim_action", queue="short_tasks", soft_time_limit=600)
|
||||||
def post_trim_action(friendly_token):
|
def post_trim_action(friendly_token):
|
||||||
"""Perform post-processing actions after video trimming
|
"""Perform post-processing actions after video trimming
|
||||||
|
|||||||
@@ -259,17 +259,19 @@ def video_chapters(request, friendly_token):
|
|||||||
data = json.loads(request.body)["chapters"]
|
data = json.loads(request.body)["chapters"]
|
||||||
chapters = []
|
chapters = []
|
||||||
for _, chapter_data in enumerate(data):
|
for _, chapter_data in enumerate(data):
|
||||||
start_time = chapter_data.get('start')
|
start_time = chapter_data.get('startTime')
|
||||||
title = chapter_data.get('title')
|
end_time = chapter_data.get('endTime')
|
||||||
if start_time and title:
|
text = chapter_data.get('text')
|
||||||
|
if start_time and end_time and text:
|
||||||
chapters.append(
|
chapters.append(
|
||||||
{
|
{
|
||||||
'start': start_time,
|
'startTime': start_time,
|
||||||
'title': title,
|
'endTime': end_time,
|
||||||
|
'text': text,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
except Exception as e: # noqa
|
except Exception as e: # noqa
|
||||||
return JsonResponse({'success': False, 'error': 'Request data must be a list of video chapters with start and title'}, status=400)
|
return JsonResponse({'success': False, 'error': 'Request data must be a list of video chapters with startTime, endTime, text'}, status=400)
|
||||||
|
|
||||||
ret = handle_video_chapters(media, chapters)
|
ret = handle_video_chapters(media, chapters)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user