Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Writing video from bytes produces corrupted video with Dropzone #2223

Open
tengerdata opened this issue Feb 19, 2023 · 2 comments
Open

Writing video from bytes produces corrupted video with Dropzone #2223

tengerdata opened this issue Feb 19, 2023 · 2 comments

Comments

@tengerdata
Copy link

My goal is to chunk client-side video uploads to separate .mp4 files that are under 100MB in size. I came across an open source library Dropzone.js that can accomplish the task I want to achieve.

Bits and pieces of my current code.

templates/upload.html:

<script type="application/javascript">
Dropzone.options.dropper = {
    paramName: 'file',
    chunking: true,
    maxFiles: 1,
    dictDefaultMessage: "Upload Match Video",
    acceptedFiles: ".mp4",
    forceChunking: true,
    url: '/tutorial',
    maxFilesize: 6144, // megabytes
    chunkSize: 100000000 // bytes
}
</script>

<center>
<form method="POST" action='/upload' class="dropzone dz-clickable"
      id="dropper" enctype="multipart/form-data">
</form>
</center>

flask_app.py:

@app.route('/upload', methods=['GET', 'POST'])
def upload():
    if request.method == "GET":
        return render_template('upload.html', static_folder='static')
    f = request.files['file']
    filename = secure_filename(f.filename)
    path_to_video = os.path.join(app.config['UPLOAD_FOLDER'], filename)
    fsr = f.stream.read()
    chunkfilename = path_to_video[:-4] + f'_Chunk{int(request.form["dzchunkindex"]) + 1}.mp4'
    with open(chunkfilename, "wb") as out_file:
        out_file.write(fsr)
    f.close()
    if int(request.form['dzchunkindex']) + 1 == int(request.form['dztotalchunkcount']):
        return redirect("/video")
    return make_response(("Chunk upload successful", 200))

Directory structure:

app/
   static/
         uploaded_file.mp4
   templates/
         upload.html
   flask_app.py

My goal:

app/
   static/
         uploaded_file_chunk1.mp4
         uploaded_file_chunk2.mp4
         uploaded_file_chunk3.mp4
   templates/
         upload.html
   flask_app.py

My current problem is that the chunked video clips that are outputted become corrupted video files. I cannot play them in VLC or Windows Media Player, they either raise an error message, or just freeze.

I can see that they are chunked properly, since a 145MB video gets split into two .mp4 videos with the first chunk being just under 100MB, and the second chunk being the other 45MB. What gives me hope is that when I used an online corrupted video fixer (https://fix.video/), I can see that the broken contents of the video are recovered as what I expected; however, I don't know how to fix it in my code.

Any help appreciated. Thanks very much.

@magic-thomas
Copy link

magic-thomas commented Feb 22, 2023

Same issue here.

Some files are uploaded ok. But usually Video files is not uploaded ok.

MP4Box say it is truncated on server.

And the each md5 hash values are different.

In my case, files which size is more than 200MB makes problem.

I guess it is because web workers.

Before I try dropzonejs, I made multithreading uploader with web workers by myself but It failed with same issue.

Need help.

@pavan0450
Copy link

Hi @magic-thomas and @tengerdata , I tried multi-part upload for large files using web-workers, but i see that it still freezes the UI interactions somehow (the ui shouldn't freeze since i'm using webworkers).
wondering if this "dropzone" package can do the multi-part upload without FREEZING the ui ? any ideas ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants