Skip to content

Commit

Permalink
Merge pull request #12 from wandenberg/master
Browse files Browse the repository at this point in the history
Adding option to move moov atom to the end of the file. Fixes #12.
  • Loading branch information
danielgtaylor committed Oct 30, 2013
2 parents 49b4069 + ebc6790 commit a9dd6ed
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 14 deletions.
5 changes: 4 additions & 1 deletion qtfaststart/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ def run():
parser.add_option("-l", "--list", dest="list", default=False,
action="store_true",
help="List top level atoms")
parser.add_option("-e", "--to_end", dest="to_end", default=False,
action="store_true",
help="Move moov atom to the end of file")
parser.add_option("-s", "--sample", dest="sample", default=False,
action="store_true",
help="Create a small sample of the input file")
Expand Down Expand Up @@ -70,7 +73,7 @@ def run():
limit = 4 * (1024 ** 2)

try:
processor.process(args[0], outfile, limit = limit)
processor.process(args[0], outfile, limit = limit, to_end = options.to_end)
except FastStartException:
# A log message was printed, so exit with an error code
raise SystemExit(1)
Expand Down
38 changes: 25 additions & 13 deletions qtfaststart/processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def _find_atoms_ex(parent_atom, datastream):
datastream.seek(atom.position + atom.size)


def process(infilename, outfilename, limit=float('inf')):
def process(infilename, outfilename, limit=float('inf'), to_end=False):
"""
Convert a Quicktime/MP4 file for streaming by moving the metadata to
the front of the file. This method writes a new file.
Expand Down Expand Up @@ -183,15 +183,20 @@ def process(infilename, outfilename, limit=float('inf')):
log.info("Removing strange zero atom at %s (8 bytes)" % atom.position)

# Offset to shift positions
offset = moov_atom.size - free_size

offset = - free_size
if moov_pos < mdat_pos:
# moov appears to be in the proper place, don't shift by moov size
offset -= moov_atom.size
if not free_size:
# No free atoms and moov is correct, we are done!
log.error("This file appears to already be setup for streaming!")
raise FastStartException()
if to_end:
# moov is in the wrong place, shift by moov size
offset -= moov_atom.size
else:
if not to_end:
# moov is in the wrong place, shift by moov size
offset += moov_atom.size

if offset == 0:
# No free atoms and moov is correct, we are done!
log.error("This file appears to already be setup!")
raise FastStartException()

# Read and fix moov
moov = _patch_moov(datastream, moov_atom, offset)
Expand All @@ -206,10 +211,8 @@ def process(infilename, outfilename, limit=float('inf')):
datastream.seek(atom.position)
outfile.write(datastream.read(atom.size))

# Write moov
bytes = moov.getvalue()
log.debug("Writing moov... (%d bytes)" % len(bytes))
outfile.write(bytes)
if not to_end:
_write_moov(moov, outfile)

# Write the rest
atoms = [item for item in index if item.name not in ["ftyp", "moov", "free"]]
Expand All @@ -224,13 +227,22 @@ def process(infilename, outfilename, limit=float('inf')):
for chunk in get_chunks(datastream, CHUNK_SIZE, cur_limit):
outfile.write(chunk)

if to_end:
_write_moov(moov, outfile)

# Close and set permissions
outfile.close()
try:
shutil.copymode(infilename, outfilename)
except:
log.warn("Could not copy file permissions!")

def _write_moov(moov, outfile):
# Write moov
bytes = moov.getvalue()
log.debug("Writing moov... (%d bytes)" % len(bytes))
outfile.write(bytes)

def _patch_moov(datastream, atom, offset):
datastream.seek(atom.position)
moov = io.BytesIO(datastream.read(atom.size))
Expand Down

0 comments on commit a9dd6ed

Please sign in to comment.