Issue playing base64 song file from server wrote to local file system with FileSystem

Hello everyone,

Let’s begin with basics informations:

My expo diagnostics result:

Expo CLI 4.6.0 environment info:
System:
OS: Linux 4.4 Debian GNU/Linux 10 (buster) 10 (buster)
Shell: 5.0.3 - /bin/bash
Binaries:
Node: 16.11.1 - ~/.nvm/versions/node/v16.11.1/bin/node
npm: 8.0.0 - ~/.nvm/versions/node/v16.11.1/bin/npm
Watchman: 2021.10.18.00 - /home/linuxbrew/.linuxbrew/bin/watchman
npmPackages:
@expo/webpack-config: ^0.16.6 => 0.16.6
expo: ^39.0.0 => 39.0.5
react: 16.13.1 => 16.13.1
react-dom: 16.13.1 => 16.13.1
react-native: https://github.com/expo/react-native/archive/sdk-39.0.3.tar.gz => 0.63.2
react-native-web: ~0.13.7 => 0.13.18
npmGlobalPackages:
expo-cli: 4.6.0
Expo Workflow: managed

So why am i here? Well i try running my app on android from a basic song player component to read some audio file in base64 format provided by my Back-Office.

My component:

import React from "react";
import { StyleSheet, Text, View } from "react-native";
import { TouchableOpacity } from "react-native-gesture-handler";
import * as FileSystem from 'expo-file-system'
import { Audio } from 'expo-av';
import PlaySvg from '../assets/images/play.svg';
import { PatientResponseType } from "../enums/patientResponseType";
import { FileExtensionsType } from "../enums/fileExtensionsType";

type Props = {
    saveMethod?: (response: string, responseType: PatientResponseType, fileExtensionType?: FileExtensionsType) => void;
    fileName: string;
    base64: string;
    isSelectable: boolean;
};

export default function SoundPlayer({ saveMethod, fileName, base64, isSelectable } : Props){
    
    async function playSound() {
        let sound = new Audio.Sound();
        var uri = `${FileSystem.documentDirectory}${fileName}`;
        
        let file = await FileSystem.getInfoAsync(uri);
        console.log(`file: ${JSON.stringify(file, null, 4)}`);
        if (!file.exists){
            await FileSystem.writeAsStringAsync(uri, `data:audio/m4a;base64,${base64}`, { encoding: FileSystem.EncodingType.Base64 });
        } else {
            console.log ('----------- DELETING FILE MP3 ----------------');
            await FileSystem.deleteAsync(uri);
            await FileSystem.writeAsStringAsync(uri, `data:audio/m4a;base64,${base64}`, { encoding: FileSystem.EncodingType.Base64 });
        }
        console.log('-------------------FILE FOUND -----------------------------');
        console.log(uri);
        try {
            await sound.loadAsync({ uri: uri }, undefined, false); // Here the error is throwned
            console.log('---------------------FILE LOADED ---------------------------------');
            sound.playAsync();
            await sound.unloadAsync();
        } catch(error){
            console.log(error);
        }
    }

    return (isSelectable && saveMethod !== undefined) ? (
        <View style={styles.soundSelectorContainer}>
            <TouchableOpacity 
                onPress={() => playSound()}
                style={styles.playButton}
            >
                <PlaySvg width="30" height="30" color="grey" />
            </TouchableOpacity>
            <TouchableOpacity
                style={styles.selectionButton}
                onPress={() => saveMethod(base64, PatientResponseType.File, FileExtensionsType.M4a)}
            >
                <Text style={{color: 'white' }}>Choisir</Text>
            </TouchableOpacity>
        </View>
    ) : (
        <TouchableOpacity 
            onPress={() => playSound()}
            style={styles.playButton}
        >
            <PlaySvg width="30" height="30" color="grey" />
        </TouchableOpacity>
    );
}

const styles = StyleSheet.create({
    soundSelectorContainer:{
        flexDirection:"column",
        alignItems: 'center',
        justifyContent: 'center'
    },
    playButton: {
        width: 25,
        height: 25,
        padding: 25,
        marginBottom: 20,
        borderRadius: 80,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'white'
    },
    selectionButton: {
        backgroundColor: "black",
        borderRadius: 30,
        borderBottomWidth: 1,
        width: 100,
        height: 45,
        marginBottom: 20,
        flexDirection: "row",
        justifyContent: 'center',
        alignItems: "center"
    }
});

And the console stack is :

Running application on device.
Requesting permissions…
file: {
“modificationTime”: 1635596333,
“size”: 17,
“uri”: “file:///data/user/0/host.exp.exponent/files/ExperienceData/UNVERIFIED-ip-AppName/sonnette.m4a”,
“isDirectory”: false,
“exists”: true
}
----------- DELETING FILE MP3 ----------------
-------------------FILE FOUND -----------------------------
file:///data/user/0/host.exp.exponent/files/ExperienceData/UNVERIFIED-ip-AppName/sonnette.m4a
f.g.b.d.q0.f0: None of the available extractors (e, g, i, e, g, e, d0, c, d, w, b, b) could read the stream.
at node_modules/react-native/Libraries/BatchedBridge/NativeModules.js:103:50 in promiseMethodWrapper
at node_modules/@unimodules/react-native-adapter/build/NativeModulesProxy.native.js:15:23 in moduleName.methodInfo.name
at http://ip:port/node_modules/expo/AppEntry.bundle?platform=android&dev=true&hot=false&minify=false:161541:52 in
at node_modules/expo-av/build/Audio/Sound.js:90:38 in loadAsync
at [native code]:null in flushedQueue
at [native code]:null in invokeCallbackAndReturnFlushedQueue

What i tried until now is changing the file format, i tried with mp3 too, I tried adding MediaPlayer but still getting an error.

Thanks in advance for your Help!

Seems i cannot edit the post i add some additionnal informations here, the error is throwing when i call the loadAsync method. it’s seems like he don’t recognize the file extension. I tried to call the method in this way too, without success:

sound.loadAsync({uri: uri})

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.