Project

General

Profile

« Previous | Next » 

Revision a11df5e5

Added by David Sorber over 7 years ago

It works! Need to add some polish before we're ready to call it 0.1, but
nearly there!

View differences:

software/hbkcd/hbkcd/config.py
# Absolute path the to the HandbrakeCLI executable
HANDBRAKE_PATH = '/opt/local/bin/HandBrakeCLI'
HANDBRAKE_CMD = [HANDBRAKE_PATH, '-i', '', '-o', '/home/dsorber/clip-OUT.mkv',
'-f', 'av_mkv', '-e', 'x265', '--encoder-preset', 'veryslow',
'--encoder-level', 'auto', '-q', '24', '-2', '-T', '-r',
'23.98', '-E', 'copy:aac']
# Absolute path to the ffprobe executable
FFPROBE_PATH = '/home/dsorber/ffprobe'
# The ffprobe command used to get information about the video file
FFPROBE_CMD = '{:s} -show_streams -show_entries stream=width,height,'\
'display_aspect_ratio,r_frame_rate,bit_rate,codec_type,'\
'codec_name -of json -v quiet -i "{:s}"'
FFPROBE_CMD = [FFPROBE_PATH, '-show_streams', '-show_entries',
'stream=width,height,display_aspect_ratio,r_frame_rate,'
'bit_rate,codec_type,codec_name', '-of', 'json', '-v', 'quiet',
'-i', '']
# Command server port
COMMAND_SERVER_PORT = 8081
software/hbkcd/hbkcd/daemon.py
#!/usr/bin/python3
import datetime
import logging
import os
import subprocess
import sys
import threading
import time
from hbkcd.config import *
from hbkcd.command_server import StoppableHTTPServer, CommandHandler
# ~ from hbkcd.queue import ENCODE_QUEUE
from hbkcd.queue import ENCODE_QUEUE
#
# HbkCD - Handbrake Control Daemon
......
try:
while True:
time.sleep(1)
item = ENCODE_QUEUE.get_next()
if item is None:
continue
# Mark next item as in progress
item.in_progress = True
item.encode_started = datetime.datetime.now()
# Start Handbrake process
cmd = HANDBRAKE_CMD
cmd[2] = item.path
hbk_proc = subprocess.Popen(cmd,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
encoding='utf-8')
# Create an interator to the stdout of the process so we can
# monitor status
proc_stdout = iter(hbk_proc.stdout.readline, '')
status_thread = threading.Thread(target=item.update_status,
args=(proc_stdout,))
status_thread.start()
# Let the HandBrake process run and print a message to the log
# every minute
ctr = 0
while hbk_proc.poll() is None:
ctr += 1
if ctr % 60 == 0:
logging.info('Encode in progress... {:s}'.format(ctr, item.status))
ctr = 0
time.sleep(1)
item.encode_finished = datetime.datetime.now()
status_thread.join()
item.in_progress = False
if hbk_proc.returncode == 0:
logging.info('Encode of {:s} completed!'.format(item.path))
else:
logging.error('Error while encoding {:s}'.format(item.path))
# Remove the item from the queue
ENCODE_QUEUE.remove(0)
except KeyboardInterrupt:
logging.warn('Command server interrupted')
finally:
software/hbkcd/hbkcd/queue.py
item.position = position
def remove(self, idx):
# TODO: implement removal
pass
if idx >= len(self.queue):
logging.error('Invalid index: {:d}'.format(idx))
return False
if self.queue[idx].in_progress:
logging.error('Unable to remove index {:d}; encode in progress'
.format(idx))
return False
logging.debug('Removing index: {:d}'.format(idx))
self.queue.pop(idx)
# Re-set positions for all items
ctr = 1
for item in self.queue[]
item.position = ctr
ctr += 1
return True
def get_list(self):
""" Get queue as a list of dicts that can be converted to JSON easily
"""
return [item.get_dict_rep() for item in self.queue]
def get_next(self):
if not self.queue:
return None
else:
return self.queue[0]
class QueueItem(object):
......
self.filename = os.path.basename(path)
self.position = None
self.in_progress = False
self.status = 'queued'
# Video
self.width = None
......
def probe(self):
# Fill in ffprobe command
cmd = FFPROBE_CMD.format(FFPROBE_PATH, self.path)
proc = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE,
cmd = FFPROBE_CMD
cmd[9] = self.path
proc = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
probe_okay = True
......
return {'position': self.position,
'path': self.path,
'in_progress': self.in_progress,
'status': self.status,
'width': self.width,
'height': self.height,
'framerate': self.framerate,
......
'encode_started': format_ds(self.encode_started),
'encode_finished': format_ds(self.encode_finished)}
def update_status(self, stdout_iter):
logging.info('Update status thread running for: {:s}'.format(self.path))
for stdout_line in stdout_iter:
# Naturally this is very specific parsing for the HBK output
try:
self.status = stdout_line.strip().split(',', 1)[1].strip()
except IndexError:
self.status = stdout_line
logging.info('Update status thread terminating')
# Does this need to be protected?
ENCODE_QUEUE = EncodeQueue()
software/hbkcd/setup.py
setup(
name = 'hbkcd',
version = '0.0.2',
version = '0.0.3',
description = 'HandBrake Control Daemon',
packages = find_packages(),
python_requires = '>=3.6.0',

Also available in: Unified diff