Project

General

Profile

« Previous | Next » 

Revision a5afc963

Added by David Sorber over 7 years ago

Add remove command and helper scripts.

View differences:

software/hbkcd/hbkcd/command_server.py
response_dict['message'] = 'Command format invalid'
if 'type' in content:
# Delegate potentiall valid commands for additional handling
# Delegate potentially valid commands for additional handling
if content['type'] == 'add':
response = self.handle_add_cmd(content)
response_dict['success'] = response[0]
response_dict['message'] = response[1]
elif content['type'] == 'remove':
response = self.handle_remove_cmd(content)
response_dict['success'] = response[0]
response_dict['message'] = response[1]
except Exception as exp:
response_dict['success'] = False
......
def handle_add_cmd(self, command_data):
""" Handler for the "add" command
"""
if 'path' not in command_data:
if 'path' not in command_data or 'output' not in command_data:
return False, 'Command format invalid'
# Check if the path actually exists:
......
msg = msg.format(path, mimetype)
logging.error(msg)
return False, msg
# Check output default assume that the path is a direct file name
output_path = command_data['output']
if output_path[-4:].lower() not in ['.mkv', '.mp4']:
# Assume output directory, name output based on input filename
if not os.path.isdir(output_path):
try:
os.makedirs(output_path, exist_ok=True)
except PermissionError:
msg = 'Unable to create output directory: {:s}'
msg = msg.format(output_path)
logging.error(msg)
return False, msg
# Always default to Matroska output
filename = os.path.basename(path)
output_filename = '{:s}.mkv'.format(os.path.splitext(filename)[0])
# Build final output path
output_path = os.path.join(output_path, output_filename)
# Create a QueueItem instance and then probe the file to retrieve its
# attributes
item = QueueItem(path)
item = QueueItem(path, output_path)
if not item.probe():
msg = 'An error ocurred while probing the video file'
logging.error(msg)
......
return True, 'Added to queue'
def handle_remove_cmd(self, command_data):
""" Handler for the "remove" command
"""
if 'position' not in command_data:
return False, 'Command format invalid'
position = int(command_data['position'])
success = ENCODE_QUEUE.remove(position - 1)
msg = 'Removed element {:d}'.format(position)
if not success:
msg = 'Failed to remove element {:d}'.format(position)
return success, msg
def main():
print('starting server...')
software/hbkcd/hbkcd/config.py
'-f', 'av_mkv', '-e', 'x265', '--encoder-preset', 'veryslow',
'--encoder-level', 'auto', '-q', '24', '-2', '-T', '-r',
'23.98', '-E', 'copy:aac']
HANDBRAKE_CMD_INPUT_IDX = 2
HANDBRAKE_CMD_OUTPUT_IDX = 4
HANDBRAKE_CMD_FPS_IDX = 18
HANDBRAKE_CMD_AUDIO_IDX = 20
# Absolute path to the ffprobe executable
FFPROBE_PATH = '/home/dsorber/ffprobe'
software/hbkcd/hbkcd/daemon.py
item.encode_started = datetime.datetime.now()
# Start Handbrake process
cmd = HANDBRAKE_CMD
cmd[2] = item.path
cmd = item.build_hbk_cmd()
hbk_proc = subprocess.Popen(cmd,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
......
status_thread.start()
# Let the HandBrake process run and print a message to the log
# every minute
# every 5 minutes
logging.info('Start encode of {:s}'.format(item.path))
ctr = 0
while hbk_proc.poll() is None:
ctr += 1
if ctr % 60 == 0:
logging.info('Encode in progress... {:s}'.format(ctr, item.status))
if ctr % 300 == 0:
logging.info('Encode in progress... {:s}'.format(item.status))
ctr = 0
time.sleep(1)
......
status_thread.join()
item.in_progress = False
# Calculate elapsed time
elapsed = item.encode_finished - item.encode_started
hours, remainder = divmod(elapsed.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
elapsed_str = '{:02}:{:02}:{:02}'
elapsed_str = elapsed_str.format(int(hours), int(minutes), int(seconds))
# Print success or failure message to the log depending on the
# HandBrake process's return code
if hbk_proc.returncode == 0:
logging.info('Encode of {:s} completed!'.format(item.path))
logging.info('Encode of {:s} completed in {:s}'.format(item.path,
elapsed_str))
else:
logging.error('Error while encoding {:s}'.format(item.path))
software/hbkcd/hbkcd/queue.py
# Re-set positions for all items
ctr = 1
for item in self.queue[]
for item in self.queue:
item.position = ctr
ctr += 1
......
class QueueItem(object):
def __init__(self, path):
def __init__(self, path, output_file):
self.path = path
self.filename = os.path.basename(path)
self.output_file = output_file
self.position = None
self.in_progress = False
self.status = 'queued'
......
def get_dict_rep(self):
return {'position': self.position,
'path': self.path,
'output_file': self.output_file,
'in_progress': self.in_progress,
'status': self.status,
'width': self.width,
......
'encode_finished': format_ds(self.encode_finished)}
def update_status(self, stdout_iter):
logging.info('Update status thread running for: {:s}'.format(self.path))
logging.debug('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')
logging.debug('Update status thread terminating')
def build_hbk_cmd(self):
""" Build and return templated HandBrake command.
"""
cmd = HANDBRAKE_CMD
cmd[HANDBRAKE_CMD_INPUT_IDX] = self.path
cmd[HANDBRAKE_CMD_OUTPUT_IDX] = self.output_file
cmd[HANDBRAKE_CMD_FPS_IDX] = self.framerate
if self.convert_audio:
# If converting audio use AAC
# TODO: double check this audio settings make sure VBR is used
cmd[HANDBRAKE_CMD_AUDIO_IDX] = 'fdk_aac --aq 5'
return cmd
# Does this need to be protected?
ENCODE_QUEUE = EncodeQueue()
software/hbkcd/scripts/hbkcd_add.sh
#!/bin/bash
ADDRESS="brutus"
PORT="8081"
if [ "$#" -ne 2 ]; then
echo "USAGE: hbkcd_add <path to input file> <path to output file/directory>"
exit -1
fi
# Make sure curl ad jq are installed
command -v curl >/dev/null 2>&1 || { echo >&2 "Please install curl to use this script. Aborting."; exit 1; }
command -v jq >/dev/null 2>&1 || { echo >&2 "Please install jq to use this script. Aborting."; exit 1; }
INPUT_PATH=$(readlink -f $1)
curl -s -X POST -d '{"type": "add", "path": "'$INPUT_PATH'", "output": "'$2'"}' http://$ADDRESS:$PORT/command | jq
software/hbkcd/scripts/hbkcd_queue.sh
#!/bin/bash
ADDRESS="brutus"
PORT="8081"
# Make sure curl ad jq are installed
command -v curl >/dev/null 2>&1 || { echo >&2 "Please install curl to use this script. Aborting."; exit 1; }
command -v jq >/dev/null 2>&1 || { echo >&2 "Please install jq to use this script. Aborting."; exit 1; }
curl -s -X GET http://$ADDRESS:$PORT/queue | jq
software/hbkcd/scripts/hbkcd_remove.sh
#!/bin/bash
ADDRESS="brutus"
PORT="8081"
if [ "$#" -ne 1 ]; then
echo "USAGE: hbkcd_remove <queue position>"
exit -1
fi
# Make sure curl ad jq are installed
command -v curl >/dev/null 2>&1 || { echo >&2 "Please install curl to use this script. Aborting."; exit 1; }
command -v jq >/dev/null 2>&1 || { echo >&2 "Please install jq to use this script. Aborting."; exit 1; }
curl -s -X POST -d '{"type": "remove", "position": "'$1'"}' http://$ADDRESS:$PORT/command | jq
software/hbkcd/setup.py
setup(
name = 'hbkcd',
version = '0.0.3',
version = '0.1.0',
description = 'HandBrake Control Daemon',
packages = find_packages(),
python_requires = '>=3.6.0',

Also available in: Unified diff