Created
January 9, 2022 00:46
-
-
Save Palisand/5337aea19792e26548337e548096ee12 to your computer and use it in GitHub Desktop.
Old python code for transcoding images
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Helpers to transcode images. | |
DEPENDENCIES | |
------------ | |
imagemagick (for converting, already installed) | |
avconv (for transcoding) sudo apt-get install libav-tools | |
libx264 (higher encoding quality) sudo apt-get install libavcodec-extra-53 | |
http://askubuntu.com/questions/266663/ffmpeg-resize-could-not-find-codec-parameters | |
""" | |
from __future__ import absolute_import | |
import os | |
import time | |
import logging | |
import subprocess | |
from glob import glob | |
from tempfile import NamedTemporaryFile | |
from apps.services.aws.s3 import s3_bucket | |
from django.conf import settings | |
log = logging.getLogger(__name__) | |
STORAGE_DIR = '/percolate/hotlanta/apps/ugc/transcode/image/transcoded/' | |
def start_job(keyname, filename): # creator? | |
""" | |
Start a transcoding job using the given image file keyname | |
Args: | |
keyname (str) - key name of the image file to transcode | |
filename (str) - the name of the image file | |
""" | |
timestamp = str(time.time()) | |
log.debug("native transcode job started for: " + keyname) | |
with s3_bucket(settings.S3_CLIENT_UPLOAD_BUCKET) as image_bucket, NamedTemporaryFile() as fp: | |
key = image_bucket.get_key(keyname) | |
key.get_contents_to_filename(fp.name) | |
f = os.path.splitext(os.path.basename(filename))[0] | |
if filename.endswith(".gif"): | |
# handle gif: | |
_convert_gif_to_mp4(fp.name, f) | |
_update_find_a_better_name() # store video on db + s3 | |
else: | |
# handle img: | |
_convert_img_to_jpg(fp.name, f) | |
# replace img with jpg (db) | |
def _convert_gif_to_mp4(gif_path, mp4_name, quality=23): | |
""" | |
Converts a GIF to an MP4 and stores the result | |
Args: | |
gif_path (str) - the path to the gif file to convert | |
mp4_name (str) - the desired name of the resultant mpeg4 file | |
quality (int) - the desired quality of the resultant mpeg4 file | |
PLEASE NOTE: | |
Once Percolate updates to a more recent Ubuntu release, FFmpeg (the real one) can be used | |
and ALL of the code contained in this function can be substituted with one line, as follows: | |
subprocess.call('ffmpeg -i {0} -pix_fmt yuv420p -vf scale=trunc(iw/2)*2:trunc(ih/2)*2 \ | |
{1}.mp4'.format(gif_path, mp4_name).split()) | |
""" | |
ticks_per_frame = subprocess.check_output('identify -verbose -format %T_ {0}'.format(gif_path).split()).split('_')[:-1] | |
ticks_per_frame = [int(i) for i in ticks_per_frame] | |
num_frames = len(ticks_per_frame) | |
min_ticks = min(ticks_per_frame) | |
subprocess.call('convert -coalesce {0} tmp%d.png'.format(gif_path).split()) | |
if len(set(ticks_per_frame)) > 1: | |
num_dup = 0 | |
num_dup_total = 0 | |
for frame, ticks in enumerate(ticks_per_frame): | |
num_dup_total += num_dup | |
frame += num_dup_total | |
num_dup = 0 | |
if ticks > min_ticks: | |
num_dup = (ticks / min_ticks) - 1 | |
for i in range(num_frames + num_dup_total - 1, frame, -1): | |
orig = 'tmp%d.png' % i | |
new = 'tmp%d.png' % (i + num_dup) | |
subprocess.call(['mv', orig, new]) | |
for i in range(1, num_dup + 1): | |
curr = 'tmp%d.png' % frame | |
dup = 'tmp%d.png' % (i + frame) | |
subprocess.call(['cp', curr, dup]) | |
framerate = (100 / min_ticks) if min_ticks else 10 | |
subprocess.call('avconv -r {0} -i tmp%d.png -c:v libx264 -crf {1} -pix_fmt yuv420p \ | |
-vf scale=trunc(iw/2)*2:trunc(ih/2)*2 -y {2}.mp4'.format(framerate, quality, STORAGE_DIR + mp4_name).split()) | |
subprocess.call(['rm'] + glob('tmp*.png')) | |
def _convert_img_to_jpg(img_path, jpg_name): | |
""" | |
Converts an img file to a JPG and stores the result | |
Args: | |
img_file (str) - the path to the image file to convert | |
jpg_name (str) - the desired name of the resultant jpeg file | |
""" | |
# If this is going to remain a single line, might as well stick it in start_job | |
subprocess.call('convert {0} {1}.jpg'.format(img_path, STORAGE_DIR + jpg_name).split()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment