@ -3,6 +3,7 @@ import datetime
import logging
import os
import subprocess
from hashlib import sha256
from urlparse import urlparse
from uuid import uuid4
@ -21,14 +22,16 @@ class RaceNotFound(Exception):
class CantFindStart ( Exception ) :
def __init__ ( self , racer , found) :
def __init__ ( self , racer , racer_number, found, path ) :
self . racer = racer
self . racer_number = racer_number
self . found = found
self . path = path
def __str__ ( self ) :
if self . found > 0 :
return " Found multiple ( {} ) possible start points for {} " . format ( self . found , self . racer )
return " Found multiple ( {} ) possible start points for racer {} ( {} ) " . format ( self . found , self . racer_number , self . racer )
else :
return " Failed to find start point for {} ". format ( self . racer )
return " Failed to find start point for racer {} ({} ) ". format ( self . racer_number , self . racer )
def ts ( dt ) :
@ -77,7 +80,10 @@ def conn_from_url(url):
)
def review ( match_id , race_number , base_dir , db_url , start_range = ( 0 , 5 ) , finish_range = ( - 5 , 10 ) ) :
def review (
match_id , race_number , base_dir , db_url , start_range = ( 0 , 5 ) , finish_range = ( - 5 , 10 ) ,
racer1_start = None , racer2_start = None ,
) :
logger = logging . getLogger ( " review " ) . getChild ( " {} - {} " . format ( match_id , race_number ) )
conn = conn_from_url ( db_url )
@ -111,11 +117,15 @@ def review(match_id, race_number, base_dir, db_url, start_range=(0, 5), finish_r
( racer1 , racer2 , start , duration ) , = data
end = start + datetime . timedelta ( seconds = duration / 100. )
# cache hash encapsulates all input args
cache_hash = sha256 ( str ( ( match_id , race_number , start_range , finish_range , racer1_start , racer2_start ) ) )
cache_str = cache_hash . digest ( ) . encode ( ' base64 ' ) [ : 12 ]
output_name = " {} - {} - {} - {} " . format ( match_id , racer1 , racer2 , race_number )
output_dir = os . path . join ( base_dir , " reviews " , output_name )
if not os . path . exists ( output_dir ) :
os . makedirs ( output_dir )
result_name = " review_ {} _{} .mp4" . format ( * finish_range )
result_name = " review_ {} .mp4" . format ( cache_str )
result_path = os . path . join ( output_dir , result_name )
if os . path . exists ( result_path ) :
logger . info ( " Result already exists for {} , reusing " . format ( result_path ) )
@ -123,10 +133,12 @@ def review(match_id, race_number, base_dir, db_url, start_range=(0, 5), finish_r
finish_paths = [ ]
for racer_ number, racer in enumerate ( ( racer1 , racer2 ) ) :
for racer_ index, ( racer , time_offset ) in enumerate ( ( ( racer1 , racer1_start ) , ( racer2 , racer2_start ) ) ) :
nonce = str ( uuid4 ( ) )
start_path = os . path . join ( output_dir , " start- {} - {} .mp4 " . format ( racer_number , nonce ) )
racer_number = racer_index + 1
if time_offset is None :
start_path = os . path . join ( output_dir , " start- {} - {} .mp4 " . format ( racer_number , nonce ) )
logger . info ( " Cutting start for racer {} ( {} ) " . format ( racer_number , racer ) )
start_start , start_end = add_range ( start , start_range )
cut_to_file ( logger , start_path , base_dir , racer , start_start , start_end )
@ -153,9 +165,10 @@ def review(match_id, race_number, base_dir, db_url, start_range=(0, 5), finish_r
time_offset = float ( black_end . split ( ' : ' ) [ 1 ] )
else :
found = len ( lines )
logger . warning ( " Unable to detect start (expected 1 black interval, but found {} ) " . format ( found ) )
raise CantFindStart ( racer , found )
time_offset = datetime . timedelta ( seconds = time_offset )
logger . warning ( " Unable to detect start (expected 1 black interval, but found {} ), re-cutting with timestamps " . format ( found ) )
cut_to_file ( logger , start_path , base_dir , racer , start_start , start_end , frame_counter = True )
raise CantFindStart ( racer , racer_number , found , start_path )
time_offset = datetime . timedelta ( seconds = time_offset - start_range [ 0 ] )
# start each racer's finish video at TIME_OFFSET later, so they are the same
# time since their actual start.