Skip to content

Commit

Permalink
First fully operational video indexer
Browse files Browse the repository at this point in the history
  • Loading branch information
maximg committed Jun 30, 2013
1 parent f45f7eb commit 5d71f8d
Show file tree
Hide file tree
Showing 9 changed files with 172 additions and 6 deletions.
6 changes: 6 additions & 0 deletions doc/notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

:: split video in 2 parts
d:\bin\ffmpeg\bin\ffmpeg -i test.mp4 -t 00:00:20 -c copy test1.mp4 -ss 00:00:60 -c copy test2.mp4

:: reduce video size
d:\bin\ffmpeg\bin\ffmpeg -i test1.mp4 -filter:v scale=120:-1 -acodec copy test1s.mp4
21 changes: 21 additions & 0 deletions make_shoot_index.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
:: Generate index for a folder
:: Usage: make_shoot_index source

:: TODO: update index for all video folders

set LIBRARY=Video.Maxim
set DST_DRIVE=v:
set SRC=%1
set DST=%DST_DRIVE%\Video\%LIBRARY%\_index
set PYTHON=python

if '%1' == '' goto error

%PYTHON% %~dp0\make_thumbnails.py %SRC% %DST%

pause

exit /b

:error
echo Usage: make_shoot_index source
62 changes: 56 additions & 6 deletions make_thumbnails.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
# Generate thumbnails and the shoot html pages

import os
import sys
import datetime
import time
from collections import defaultdict
import shutil
from subprocess import call
import jinja2

# download ffmpeg from the web
ffmpeg_bin = "d:\\bin\\ffmpeg\\bin\\ffmpeg.exe"

templateLoader = jinja2.FileSystemLoader( searchpath="D:\\Projects\\GitHub\\phototools\\templates" )
templateEnv = jinja2.Environment( loader=templateLoader )

def build_shot_html(shotId, thumbnails, destdir):
template = templateEnv.get_template( "shot.jinja" )
templateVars = { "title" : "Shot: %s" % shotId,
"description" : "TODO",
"thumbnails" : thumbnails
}
with open(os.path.join(destdir, "%s.html" % shotId), "w") as text_file:
text_file.write( template.render( templateVars ) )

def build_shoot_html(shots, destdir):
template = templateEnv.get_template( "shoot.jinja" )
templateVars = { "title" : "Shoot",
"description" : "TODO",
"shots" : shots
}
with open(os.path.join(destdir, "index.html"), "w") as text_file:
text_file.write( template.render( templateVars ) )

def file_basename(aFile):
return os.path.splitext(os.path.basename(aFile))[0]

Expand All @@ -18,9 +42,17 @@ def is_video(aFile):

def make_thumbnails(aFile, destdir):
print "Generating thumbnails for %s" % (aFile)
call([ffmpeg_bin, "-i", aFile, "-r", "1", "%s\\%s.%%04d.jpg" % (destdir, file_basename(aFile))])
call([ffmpeg_bin, "-i", aFile, "-r", "1", "%s.%%04d.jpg" % os.path.join(destdir, file_basename(aFile))])
thumbnails = []
for root, subFolders, files in os.walk(destdir):
for aFile in files:
extension = os.path.splitext(aFile)[1]
if extension.lower() == ".jpg":
thumbnails.append( os.path.join(destdir, aFile) )
return thumbnails

def make_all_thumbnails(sourcedir, destdir):
def index_shoot(sourcedir, destdir):
shots = []
for root, subFolders, files in os.walk(sourcedir):
for aFile in files:
if is_video(aFile):
Expand All @@ -29,8 +61,14 @@ def make_all_thumbnails(sourcedir, destdir):
if os.path.exists(file_destdir):
continue
os.makedirs(file_destdir)
make_thumbnails(fullpath, file_destdir)
thumbnails = make_thumbnails(fullpath, file_destdir)
build_shot_html(aFile, thumbnails, file_destdir)
shots.append( {
"thumbnail": os.path.join(file_destdir, "%s.0001.jpg" % file_basename(aFile)),
"location": os.path.join(file_destdir, "%s.html" % aFile)
} )
#print "%s has file %s, mod date %s" % (root, ff, mod_date)
build_shoot_html(shots, destdir)

def onerror(func, path, exc_info):
"""
Expand All @@ -50,8 +88,8 @@ def onerror(func, path, exc_info):
func(path)
else:
raise
if __name__ == "__main__":

def run_test():
rootroot = "c:\\Users\\golov\\Documents"
rootroot = "d:\\Projects"
root = rootroot + "\\GitHub\\phototools\\test\\make_thumbnails"
Expand All @@ -63,10 +101,22 @@ def onerror(func, path, exc_info):
for dir in ("source", "dest"):
shutil.copytree(os.path.join(root, dir), os.path.join(workdir, dir))

make_all_thumbnails(
index_shoot(
os.path.join(workdir, "source"),
os.path.join(workdir, "dest"))

if False:
if not compare_tree( workdir, os.path.join(root, "expected")):
print "ERROR: test failed"

if __name__ == "__main__":
if 1 == 0:
run_test()
exit
if len(sys.argv) < 3:
print "Usage: make_shoot_index.py source_folder dest_folder"
exit()

index_shoot(
sys.argv[1],
os.path.join(sys.argv[2], sys.argv[1]))
23 changes: 23 additions & 0 deletions shot.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

<title>Test Example</title>
<meta name="description" content="A simple inquiry of function." />
</head>

<body>

<div id="content">
<ul>

<li>0001.jpg</li>

<li>0002.jpg</li>

</ul>
</div>

</body>
</html>
31 changes: 31 additions & 0 deletions templates/shoot.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

<title>{{ title }}</title>
<meta name="description" content="{{ description }}" />
</head>

<body>

<div id="content">
<table>
{% for item in shots %}
{% if loop.index0 is divisibleby 6 %}
<tr>
{% endif %}
<td>
<a href="{{ item.location }}">
<img src="{{ item.thumbnail }}" width="150" height="120"/>
</a>
</td>
{% if loop.index is divisibleby 6 %}
</tr>
{% endif %}
{% endfor %}
</table>
</div>

</body>
</html>
35 changes: 35 additions & 0 deletions templates/shot.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />

<title>{{ title }}</title>
<meta name="description" content="{{ description }}" />
</head>

<body>

<h1>{{ title }}<h1/>

<div id="content">
<a href="..">Back</a>
<table>
{% for item in thumbnails %}
{% if loop.index0 is divisibleby 6 %}
<tr>
{% endif %}
<td>
<a href="{{ item }}">
<img src="{{ item }}" width="150" height="120"/>
</a>
</td>
{% if loop.index is divisibleby 6 %}
</tr>
{% endif %}
{% endfor %}
</table>
<a href="..">Back</a>
</div>

</body>
</html>
Binary file removed test/make_thumbnails/source/test.mp4
Binary file not shown.
Binary file added test/make_thumbnails/source/test1s.mp4
Binary file not shown.
Binary file added test/make_thumbnails/source/test2s.mp4
Binary file not shown.

0 comments on commit 5d71f8d

Please sign in to comment.