import cv2
import os
import ffmpeg
from tempfile import mkdtemp, NamedTemporaryFile
from shutil import rmtree
def convert_to_mov(input_file: str, output_file: str = None):
# if there is no output file specified, create a temp file then return contents
if output_file == None:
tmpdir = mkdtemp()
tmp = os.path.join(tmpdir, "vid.mov")
convert_to_mov(input_file, tmp)
with open(tmp, "rb") as tmpfile:
contents = tmpfile.read()
rmtree(tmpdir)
return contents
inp = ffmpeg.input(input_file)
out = ffmpeg.output(inp, output_file, f='mov', vcodec='copy', acodec='copy')
ffmpeg.run(out)
def get_thumbnail_from_mov(input_file: str, output_file: str = None):
# if there is no output file specified, create a temp file and then return contents
if output_file == None:
tmpdir = mkdtemp()
tmp = os.path.join(tmpdir, "thumb.png")
get_thumbnail_from_mov(input_file, tmp)
with open(tmp, "rb") as tmpfile:
contents = tmpfile.read()
rmtree(tmpdir)
return contents
inp = ffmpeg.input(input_file, ss=0)
out = ffmpeg.output(inp, output_file, vframes=1)
ffmpeg.run(out)
def get_thumbnail_from_contents(contents: bytes, output_file: str = None):
with NamedTemporaryFile("rb+", suffix=".mov") as inp_file:
inp_file.write(contents)
contents = get_thumbnail_from_mov(inp_file.name, output_file)
return contents
def create_caml(video_path: str, output_file: str, auto_reverses: bool, update_label=lambda x: None):
cam = cv2.VideoCapture(video_path)
assets_path = os.path.join(output_file, "assets")
frame_count = int(cam.get(cv2.CAP_PROP_FRAME_COUNT))
FRAME_LIMIT = 300
reverse = 0
if auto_reverses:
reverse = 1
if frame_count > FRAME_LIMIT:
raise Exception(f"Videos must be under {FRAME_LIMIT} fps to loop. Either reduce the frame rate or make it shorter.")
try:
# creating a folder named data
if not os.path.exists(assets_path):
os.makedirs(assets_path, exist_ok=True)
# if not created then raise error
except OSError:
print ('Error: Creating directory of data')
# frame
currentframe = 0
width = int(cam.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cam.get(cv2.CAP_PROP_FRAME_HEIGHT))
with open(os.path.join(output_file, "main.caml"), "w") as caml:
# write caml header
fps = cam.get(cv2.CAP_PROP_FPS)
duration = frame_count / fps
caml.write(f"""
\n""")
while(True):
# reading from frame
ret,frame = cam.read()
if ret:
# if video is still left continue creating images
name = 'assets/' + str(currentframe) + '.jpg'
if update_label:
update_label('Creating...' + name)
print('Creating...' + name)
# writing the extracted images
cv2.imwrite(os.path.join(output_file.removeprefix(u"\\\\?\\"), name), frame)
caml.write(f"\t\t\t\n")
# increasing counter so that it will
# show how many frames are created
currentframe += 1
else:
break
caml.write("""
""")
# Release all space and windows once done
cam.release()
cv2.destroyAllWindows()
# Write the other caml
with open(os.path.join(output_file, "index.xml"), "w") as index:
index.write(f"""
assetManifest
assetManifest.caml
documentHeight
{height}
documentResizesToView
documentWidth
{width}
dynamicGuidesEnabled
geometryFlipped
guidesEnabled
interactiveMouseEventsEnabled
interactiveShowsCursor
interactiveTouchEventsEnabled
loopEnd
0.0
loopStart
0.0
loopingEnabled
multitouchDisablesMouse
multitouchEnabled
presentationMouseEventsEnabled
presentationShowsCursor
presentationTouchEventsEnabled
rootDocument
main.caml
savesWindowFrame
scalesToFitInPlayer
showsTouches
snappingEnabled
timelineMarkers
[(null)]
touchesColor
1 1 0 0.8
unitsInPixelsInPlayer
""")