Skip to content

Commit

Permalink
Add tools to generate keyframes for old video (#13)
Browse files Browse the repository at this point in the history
* fix some bugs, add a generate-kf feature

* change file name for generate-keyframes-preview.py

* update CHANGELOG.md and requirements.txt
  • Loading branch information
EverettSummer authored Oct 28, 2023
1 parent 3c62af0 commit 49ec999
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 16 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 4.4.1
- fix bugs for unicode issue
- Add generate script for old video_file

## 4.4.0
- Add support for keyframe and thumbnail from mira-video-manager
- metadata will not from this service but from mira-video-manager
Expand Down
74 changes: 74 additions & 0 deletions generate-keyframes-preview.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import subprocess
from math import sqrt, ceil, floor

from utils.SessionManager import SessionManager

# Unused domain is necessary
from domain.Bangumi import Bangumi
from domain.Episode import Episode
from domain.InviteCode import InviteCode
from domain.TorrentFile import TorrentFile
from domain.User import User
from domain.base import Base
from domain.Feed import Feed
from domain.Favorites import Favorites
from domain.ServerSession import ServerSession
from domain.WatchProgress import WatchProgress
from domain.Task import Task
from domain.VideoFile import VideoFile
from domain.Image import Image
from domain.Announce import Announce
from domain.WebHook import WebHook
from domain.WebHookToken import WebHookToken

import yaml
import os
import nanoid

TILE_SIZE = 10
SCALE_HEIGHT = 120
FRAMES_INTERVAL = 5000
MAX_PIC_WIDTH = 16256

def query_video_files():
fr = open('./config/config.yml', 'r')
config = yaml.load(fr)
download_location = config['download']['location']
session = SessionManager.Session()
video_file_list = session.query(VideoFile).filter(VideoFile.kf_image_path_list == None).all()
for video_file in video_file_list:
if video_file.status != VideoFile.STATUS_DOWNLOADED:
continue
video_path = download_location + '/' + str(video_file.bangumi_id) + '/' + video_file.file_path
if os.path.exists(video_path):
print('Found video_file: {0}'.format(video_path))
generate_keyframes(video_file, video_path)
session.commit()
SessionManager.Session.remove()

def generate_keyframes(video_file, video_path):
try:
video_file.tile_size = TILE_SIZE
video_file.frame_height = SCALE_HEIGHT
video_file.frame_width = int(round(SCALE_HEIGHT * video_file.resolution_w/video_file.resolution_h))
# if video_file.tile_size * video_file.frame_width > MAX_PIC_WIDTH:
# video_file.tile_size = int(floor(MAX_PIC_WIDTH/video_file.frame_width))
image_dir_path = os.path.dirname(video_path)
image_filename_base = 'keyframes-{0}'.format(nanoid.generate(8))
keyframe_image_path = image_dir_path + '/' + '{0}-%3d.jpg'.format(image_filename_base)
subprocess.check_call(['ffmpeg','-y', '-i', video_path, '-vf',
'select=isnan(prev_selected_t)+gte(t-prev_selected_t\\,2),scale={0}:{1},tile={2}x{2}'.format(
video_file.frame_width, video_file.frame_height, video_file.tile_size),
'-an', '-vsync', '0', keyframe_image_path])

filename_list = os.listdir(image_dir_path)
video_file.kf_image_path_list = []
for f in filename_list:
filename = os.path.basename(f)
if filename.endswith('.jpg') and filename.startswith(image_filename_base):
video_file.kf_image_path_list.append(f)
print('keyframe generated')
except Exception as error:
print(error)

query_video_files()
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ webencodings==0.5.1
Werkzeug==1.0.1
zipp==1.2.0
zope.interface==5.4.0
nanoid==2.0.0
8 changes: 4 additions & 4 deletions service/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ def __init__(self):
try:
if not os.path.exists(self.base_path):
os.makedirs(self.base_path)
print 'create base dir %s successfully' % self.base_path
print('create base dir %s successfully' % self.base_path)
except OSError as exception:
if exception.errno == errno.EACCES:
# permission denied
raise exception
else:
print exception
print(exception)

def __get_eps_len(self, eps):
EPISODE_TYPE = 0 # episode type = 0 is the normal episode type, even the episode is not a 24min length
Expand All @@ -87,14 +87,14 @@ def __save_bangumi_cover(self, bangumi):
try:
if not os.path.exists(bangumi_path):
os.makedirs(bangumi_path)
print 'create base dir %s successfully' % self.base_path
print('create base dir %s successfully' % self.base_path)
except OSError as exception:
if exception.errno == errno.EACCES:
# permission denied
raise exception
else:
sentry_wrapper.sentry_middleware.captureException()
print exception
print(exception)

path = urlparse(bangumi.image).path
extname = os.path.splitext(path)[1]
Expand Down
14 changes: 7 additions & 7 deletions tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,21 @@
# if bangumi folder is not existence create it
if not os.path.exists(bangumi_dir):
os.makedirs(bangumi_dir)
print 'bangumi %s folder created' % (str(bangumi.id),)
print('bangumi %s folder created' % (str(bangumi.id),))

path = urlparse(bangumi.image).path
extname = os.path.splitext(path)[1]
bangumi_cover_path = bangumi_dir + '/cover' + extname
if not os.path.exists(bangumi_cover_path):
# download bangumi image
print 'start to download bangumi cover of %s (%s)' % (bangumi.name, str(bangumi.id))
print('start to download bangumi cover of %s (%s)' % (bangumi.name, str(bangumi.id)))
file_downloader.download_file(bangumi.image, bangumi_cover_path)
if bangumi.cover_color is None:
try:
bangumi.cover_color = get_dominant_color(bangumi_cover_path, 5)
session.commit()
except Exception as err:
print err
print(err)
if bangumi.cover_image_id is None:
try:
width, height = get_dimension(bangumi_cover_path)
Expand All @@ -141,13 +141,13 @@
bangumi.cover_image = cover_image
session.commit()
except Exception as err:
print err
print(err)
except OSError as exception:
if exception.errno == errno.EACCES:
# permission denied
raise exception
else:
print exception
print(exception)

# check episode thumbnail color
eps_cur = session.query(Episode).filter(Episode.bangumi_id == bangumi.id)
Expand All @@ -158,7 +158,7 @@
episode.thumbnail_color = get_dominant_color(thumbnail_path, 5)
session.commit()
except Exception as err:
print err
print(err)
if episode.status == Episode.STATUS_DOWNLOADED and episode.thumbnail_image_id is None:
thumbnail_path = '{0}/thumbnails/{1}.png'.format(str(bangumi.id), str(episode.episode_no))
thumbnail_file_path = '{0}/{1}'.format(download_location, thumbnail_path)
Expand All @@ -169,7 +169,7 @@
height=height)
episode.thumbnail_image = thumbnail_image
session.commit()
print 'finish check bangumi #{0}'.format(str(bangumi.id))
print('finish check bangumi #{0}'.format(str(bangumi.id)))

elif args.bgm_reset:
session = SessionManager.Session()
Expand Down
8 changes: 4 additions & 4 deletions utils/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@ def __init__(self):
try:
if not os.path.exists(self.base_path):
os.makedirs(self.base_path)
print 'create base dir %s successfully' % self.base_path
print('create base dir {0} successfully'.format(self.base_path))
except OSError as exception:
if exception.errno == errno.EACCES:
# permission denied
raise exception
else:
print exception
print(exception)

def generate_thumbnail_link(self, episode, bangumi):
if episode.thumbnail_image is not None:
thumbnail_url = '/pic/{0}'.format(str(episode.thumbnail_image.file_path))
thumbnail_url = u'/pic/{0}'.format(episode.thumbnail_image.file_path)
else:
thumbnail_url = '/pic/{0}/thumbnails/{1}.png'.format(str(bangumi.id), str(episode.episode_no))
if self.image_domain is not None:
Expand Down Expand Up @@ -67,7 +67,7 @@ def generate_keyframe_image_link(self, image_path_list):

def convert_image_dict(self, image_dict):
new_dict = {
'url': '/pic/{0}'.format(image_dict['file_path']),
'url': u'/pic/{0}'.format(image_dict['file_path']),
'dominant_color': image_dict.get('dominant_color'),
'width': image_dict.get('width'),
'height': image_dict.get('height')
Expand Down
2 changes: 1 addition & 1 deletion utils/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def __init__(self):
def download_file(self, url, file_path, force_https=False):
if force_https and url.startswith('http://'):
url = url.replace('http://', 'https://', 1)
print url
print(url)
r = self.session.get(url, stream=True, proxies=self.proxy)

if r.status_code > 399:
Expand Down

0 comments on commit 49ec999

Please sign in to comment.