Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to concatenate bytes from a Content-Range HTTP request to a fully working MP4 file?

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.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading