Issue
This is my code so far, but when it concatenates the temporary files from the request to one MP4 file, the MP4 file doesn't play. The file is the same size as the uploaded file however.
@app.route('/admin/upload', methods=['POST'])
@app_key
def admin_dashboard_upload_endpoint():
# Headers
file_name = request.headers.get('Filename')
title = request.headers.get('Title')
path = f'something/path'
# Get the Content-Range header
content_range = request.headers.get('Content-Range')
# Parse the Content-Range header to get start and end bytes
start_byte, end_byte, total_size = parse_content_range(content_range)
# Get the uploaded file from the request
uploaded_file = request.files.get('File')
# Save the received bytes to a temporary file
os.makedirs('uploads', exist_ok=True)
save_to_temporary_file(uploaded_file, start_byte, end_byte)
# Check if all parts have been received
if end_byte == total_size - 1:
# If all parts are received, combine the temporary files into one
combine_temporary_files(file_name)
with open(f'uploads/{file_name}', 'rb') as combined_file:
return upload_to_storage_dashboard(combined_file, title=title, path=path, file_remove=f'uploads/{file_name}')
return "OK", 206
def parse_content_range(content_range):
# Example of content_range: 'bytes 0-999/2000'
match = re.match(r'bytes (\d+)-(\d+)/(\d+)', content_range)
if match:
start_byte, end_byte, total_size = map(int, match.groups())
return start_byte, end_byte, total_size
else:
# Handle invalid Content-Range header
return None, None, None
def save_to_temporary_file(uploaded_file, start_byte, end_byte):
temp_file_path = f'uploads/temporary_file_{start_byte}_{end_byte}.mp4'
with open(temp_file_path, 'ab') as temp_file:
temp_file.write(uploaded_file.read())
def combine_temporary_files(file_name):
combined_file_path = f'uploads/{file_name}'
temp_files = sorted([f for f in os.listdir('uploads') if f.startswith('temporary_file_')])
with open(combined_file_path, 'wb') as combined_file:
for temp_file_path in temp_files:
with open(os.path.join('uploads', temp_file_path), 'rb') as temp_file:
combined_file.write(temp_file.read())
os.remove(os.path.join('uploads', temp_file_path))
The actual code works to concatenate several Content-Range requests sent by my Flutter app, but when it puts the final MP4 together, it doesn't play. Is my approach correct or how can I achieve this? I am doing this for upload of large files.
Solution
To make my comment an answer and expanding on it a bit:
You're probably not sorting the chunks correctly. sorted()
sorts strings in lexicographical order; if you're naming your chunks like you are, you get
>>> sorted([f'chunk{x}' for x in range(1, 105) if x < 5 or x >= 100])
['chunk1', 'chunk100', 'chunk101', 'chunk102', 'chunk103', 'chunk104', 'chunk2', 'chunk3', 'chunk4']
so 1, 100, 101, 102, 103, 104, 2, 5. Oh no!
Instead, you need to name the chunks so they're lexicographically sortable, e.g.
>>> sorted([f'chunk{x:08d}' for x in range(1, 105) if x < 5 or x >= 100])
['chunk00000001', 'chunk00000002', 'chunk00000003', 'chunk00000004', 'chunk00000100', 'chunk00000101', 'chunk00000102', 'chunk00000103', 'chunk00000104']
or use another sort key altogether.
Answered By - AKX
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.