Last active
March 11, 2020 13:45
-
-
Save tatesuke/fb5ce32ad5970a3e926d5cc13bb27b97 to your computer and use it in GitHub Desktop.
ドラレコ動画のタイムラプス化
This file contains 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
import logging | |
import glob | |
import os | |
from os import path | |
from datetime import datetime | |
import subprocess | |
import re | |
# ドラレコ動画をタイムラプス化したときのコード | |
# | |
# usage : python timelapser.py | |
# | |
# メモ ffmpegのバージョン | |
# > ffmpeg -help | |
# ffmpeg version 4.2.2 Copyright (c) 2000-2019 the FFmpeg developers | |
# built with gcc 9.2.1 (GCC) 20200122 | |
# configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt | |
# libavutil 56. 31.100 / 56. 31.100 | |
# libavcodec 58. 54.100 / 58. 54.100 | |
# libavformat 58. 29.100 / 58. 29.100 | |
# libavdevice 58. 8.100 / 58. 8.100 | |
# libavfilter 7. 57.100 / 7. 57.100 | |
# libswscale 5. 5.100 / 5. 5.100 | |
# libswresample 3. 5.100 / 3. 5.100 | |
# libpostproc 55. 5.100 / 55. 5.100 | |
# Hyper fast Audio and Video encoder | |
# usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options] outfile}... | |
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s\t%(levelname)s\t%(message)s", filename="out.log") | |
DIR_INPUT = "F:\\drareco" | |
DIR_OUTPUT = "D:\\drareco2\\timelapse" | |
N_BAISOKU = 30 | |
FPS = 30 | |
#################################### | |
Logger = logging.getLogger(__name__) | |
def main(): | |
files = glob.glob("{}/**/*.MOV".format(DIR_INPUT), recursive=True) | |
Logger.debug("{} files".format(len(files))) | |
for inputFile in files: | |
Logger.info("start convert : {}".format(inputFile)) | |
try: | |
processFile(inputFile) | |
except Exception: | |
Logger.exception("unknown error", exc_info=True) | |
Logger.info("end convert") | |
def processFile(inputFile): | |
createTimestamp = path.getmtime(inputFile) | |
createDatetime = datetime.fromtimestamp(createTimestamp) | |
outFileName = "{}.mp4".format(datetime.strftime(createDatetime, "%Y-%m-%d_%H-%M-%S")) | |
outFilePath = "{}//{}".format(DIR_OUTPUT, outFileName) | |
if path.isfile(outFilePath): | |
Logger.info("file already exists.") | |
return | |
# 動画の時間取得 | |
duration = getDuration(inputFile) | |
Logger.debug("duration: {}".format(duration)) | |
os.makedirs(DIR_OUTPUT, exist_ok=True) | |
# ★ タイムアウト考慮? | |
# setpts=PTS/n -r m fps`m`で`n`倍速 | |
Logger.info("convert to {}.".format(outFilePath)) | |
command = "ffmpeg -y -i {inputFile} -filter:v \"setpts=PTS/{baisoku}\" -r {fps} -pix_fmt yuvj420p -an {outputFile}".format( | |
inputFile = inputFile, | |
baisoku = N_BAISOKU, | |
fps = FPS, | |
outputFile = outFilePath | |
) | |
Logger.debug(command) | |
result = subprocess.run(command, shell=True) | |
if result.returncode != 0: | |
raise Exception("convert failed. return code: {}".format(result.returncode)) | |
# ファイル削除 | |
# try: | |
# os.remove(inputFile) | |
# except OSError: | |
# Logger.warn("file remove failed: {}".format(inputFile)) | |
def getDuration(inputFile): | |
command = "ffprobe {} -hide_banner -show_entries format=duration".format(inputFile) | |
result = subprocess.check_output(command, shell=True) | |
for line in result.splitlines(): | |
if line.startswith(b"duration="): | |
break | |
duration = float(line.decode("utf-8").split("=")[1]) | |
return duration | |
if __name__ == "__main__" : | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment