FlutterFlow / flutterflow-issues

A community issue tracker for FlutterFlow.
109 stars 18 forks source link

Recorded audio files are corrupted on some Android devices #2749

Open DigitalLabSlash opened 3 months ago

DigitalLabSlash commented 3 months ago

Has your issue been reported?

Current Behavior

We record the user voice, send it to supabase, then download it back to the app for our user to be able to listen to his voice.

It works perfectly for some Android users, but for some others, the recorded audio file is corrupted and can't be play (even on supabase).

Expected Behavior

Recording Audio should not produce corrupt audio files, no matter the device.

Steps to Reproduce

  1. Create a recording
  2. Send to supabase
  3. Try to play the audio file with wavesurfer.js or any other player.

Reproducible from Blank

Bug Report Code (Required)

IT4ghsrhuIhgoeZE0L6Jde9WpDs6Nk84ba00sNobbxAjIoDoPJkUaczBdkxvTte7d1FHKEWKmk8FwsLQv/OeIPVePSqcR4s6+Ll6bw3zRT6/aoSRDZCSfXZ7P/9gCkvE0pi3hyNNLbZpLFoX2DuYHdyXcz3qO5P7Zwh9f6PHaOI=

Context

Imposible to release our app

Visual documentation

https://peoplesnap.slash-digital.io/ripite/Esteban.mp3 --> Recorded from Android 14 device, works perfectly https://peoplesnap.slash-digital.io/ripite/Jean.mp3 --> Recorded from Android 12 device, corrupted audio file

Additional Info

We don't know why some Android devices produce corrupted audio file when using the recording widget. It's "constant" : a device that works will always produce good audio files, a device that doesn't "work" will only produce corrupted audio files using the recording flutter flow widget.

Environment

- FlutterFlow version: v4.1.34
- Platform: Android
- Browser name and version: Not aplicable
- Operating system and version affected: Android
....
DigitalLabSlash commented 3 months ago

It seems the bug also applies while recording through the web interface

paulperez-dev commented 3 months ago

Hi @DigitalLabSlash, thanks for your report. Can you please share the list of devices you tested with the following data: brand, model, OS version.

We also need the bug report code (you can get it with a right click on the widget in the Widget Tree).

DigitalLabSlash commented 3 months ago

Hi Paul,

Thanks for your swift reply,

Here is the bug report code :

IT4ghsrhuIhgoeZE0L6Jde9WpDs6Nk84ba00sNobbxAjIoDoPJkUaczBdkxvTte7d1FHKEWKmk8FwsLQv/OeIPVePSqcR4s6+Ll6bw3zRT6/aoSRDZCSfXZ7P/9gCkvE0pi3hyNNLbZpLFoX2DuYHdyXcz3qO5P7Zwh9f6PHaOI=

So far in my testing :

Xiaomi M2011K2G Android 12 : recording is corrupted Samsung Galaxy S24 Android 14 : recording is fine Iphone6s: recording is corrupted

Also : looks similar to this : https://github.com/FlutterFlow/flutterflow-issues/issues/2316 Could be that Supabase + Some Android devices would cause trouble.

Thanks for you help

paulperez-dev commented 3 months ago

@DigitalLabSlash I will be trying to reproduce the issue and I will be back to you.

paulperez-dev commented 3 months ago

Hi @DigitalLabSlash! The team was able to reproduce the issue. I will send this to the ENG team so they can work on this.

We do appreciate your feedback, thank you!

DigitalLabSlash commented 3 months ago

Hi Paul, Amazing. Can you tell me if it's supabase related?

paulperez-dev commented 3 months ago

@DigitalLabSlash The team tested with Firebase, so it seems to be related to the audio library used by the widget.

kevinxzhou commented 3 months ago

I have the exact same issue, audio files uploaded to supabase do not play and are corrupted. The uploaded file sizes make sense however. This is a pretty major bug and should be fixed immediately as this is delaying our ability to use Flutterflow.

phils-hub commented 3 months ago

@DigitalLabSlash you mentioned this occurs in iOS too (in my issue). Is that the case?

@rzambroni can you give us an idea on when this will be fixed? My app relies completely on audio input and I basically cannot launch with this bug.

DigitalLabSlash commented 3 months ago

Yes, for some reason, some api calls work on iOS and some other don't...

In my case, if i only convert to mp3 the api call will work.... If in the api i also make the whisper transcription, the api call is blocked and I have no idea why

alih552 commented 3 months ago

I am facing the same issue, tested on Android Infinix (corrupted to the end user but playable on firebase) The weird thing is that the audio works fine for the 'sender' but doesn't work for the receivers.

rzambroni commented 3 months ago

hey @phils-hub, sorry, I

@DigitalLabSlash you mentioned this occurs in iOS too (in my issue). Is that the case?

@rzambroni can you give us an idea on when this will be fixed? My app relies completely on audio input and I basically cannot launch with this bug.

I'm very sorry but I don't have a timeline for when this will be fixed. As soon as we have more information it will be posted here.

alih552 commented 3 months ago

if anyone here have a custom action/function that solves this problem I would really appreciate it. I've more than 2,000 users affected by this issue. 😢

DigitalLabSlash commented 3 months ago

Yes Ali, we created a custom api that converts the file to true mp3 and sends a url back to the player.

`from flask import Flask, request, send_from_directory, jsonify from flask_cors import CORS import subprocess import os from werkzeug.utils import secure_filename import uuid import requests import openai

app = Flask(name) CORS(app) # Enable CORS for all domains on all routes

Base directory for handling file uploads and conversions

base_dir = os.path.join(os.getcwd(), 'audio_converts') os.makedirs(base_dir, exist_ok=True) client = openai.OpenAI(api_key="*****") # Using OpenAI class

@app.route('/convert', methods=['POST']) def convert(): if 'file' not in request.files: return jsonify(error="No file part"), 400 file = request.files['file'] if file.filename == '': return jsonify(error="No selected file"), 400

# Securely extract filename and extension
filename = secure_filename(file.filename)
file_base, file_ext = os.path.splitext(filename)
unique_id = str(uuid.uuid4())  # Generate unique ID for each file operation

# Ensure output filename is unique and preserves original extension
output_filename = f"{file_base}_{unique_id}_converted{file_ext}"
filepath = os.path.join(base_dir, f"{file_base}_{unique_id}{file_ext}")
output_path = os.path.join(base_dir, output_filename)

file.save(filepath)

try:
    # Convert the file using FFmpeg securely
    subprocess.run(['ffmpeg', '-i', filepath, '-codec:a', 'libmp3lame', '-q:a', '2', output_path], check=True)
except subprocess.CalledProcessError:
    return jsonify(error="Conversion failed"), 500

# Provide a URL for downloading the converted file
download_url = f"https://thawing-coast-39522-436006cd4744.herokuapp.com/download/{output_filename}"
return jsonify(download_url=download_url)

@app.route('/transcribe', methods=['POST']) def transcribe(): data = request.get_json() if 'fileUrl' not in data: return jsonify(error="No 'fileUrl' in request"), 400

file_url = data['fileUrl']
response = requests.get(file_url)
if response.status_code != 200:
    return jsonify(error="Failed to download the file"), 400

# Save the downloaded file
file_base = secure_filename(file_url.split('/')[-1])
file_ext = os.path.splitext(file_base)[-1]
unique_id = str(uuid.uuid4())  # Generate unique ID
filename = f"{file_base}_{unique_id}{file_ext}"
filepath = os.path.join(base_dir, filename)

with open(filepath, 'wb') as f:
    f.write(response.content)

# Transcribe the audio file using Whisper
try:
    with open(filepath, "rb") as audio_file:
        transcription = client.audio.transcriptions.create(
            model="whisper-1",
            file=audio_file
        )
    transcript_text = transcription.text
except openai.OpenAIError as e:
    logging.error("OpenAI API Error:", exc_info=True)
    return jsonify(error="Transcription failed",
                   message=str(e),
                   openai_error=e.status_code,
                   openai_error_type=str(type(e).__name__)), 500

return jsonify(transcript=transcript_text)

@app.route('/download/') def download(filename): filename = secure_filename(filename) # Re-secure filename for safe path usage return send_from_directory(base_dir, filename, as_attachment=True)

if name == 'main': app.run(debug=True)`

alih552 commented 2 months ago

Kindly, any updates regarding an ETA for the fix.

paulVu commented 1 month ago

still waiting for it

alih552 commented 1 week ago

Any updates on this?