Skip to content

Commit 81ecbe6

Browse files
maciejmakowski2003Maciej Makowski
andauthored
feat: playing audio source android (#219)
* feat: added libsndfile, rearrange external libs dir and added AudioDecoder * feat: added expo, expo document picker and expo files * refactor: refactored AudioFile example * refactor: added setting audio source from url * ci: yarn format * refactor: refactored AudioAPIInstaller and AudioAPiModule * feat: added expo to fabric app * ci: yarn format * fix: fixed AudioDecoder initialization * feat: added libsamplerate * refactor: removed unused archs * refactor: changed decoding lib to miniaudio and refactored AudioDecoder * refactor: refactored CMakeLists.txt * ci: yarn format * refactor: removed playing from url, name convention refactoring * chore: yarn lock * chore: test * ci: yarn format * ci: fix * ci: fix --------- Co-authored-by: Maciej Makowski <maciej.makowski@swmansion.com>
1 parent 7fd138a commit 81ecbe6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+95753
-708
lines changed

apps/common-app/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
"@react-navigation/native-stack": "*",
1010
"@react-navigation/stack": "*",
1111
"@shopify/react-native-skia": "*",
12+
"expo": "*",
13+
"expo-document-picker": "*",
14+
"expo-file-system": "*",
1215
"react": "*",
1316
"react-dom": "*",
1417
"react-native": "*",
@@ -26,13 +29,27 @@
2629
"@react-navigation/native-stack": "^6.11.0",
2730
"@react-navigation/stack": "^6.4.1",
2831
"@shopify/react-native-skia": "^1.5.1",
32+
"expo": "^52.0.0",
33+
"expo-document-picker": "~13.0.1",
34+
"expo-file-system": "~18.0.4",
2935
"react": "18.3.1",
3036
"react-dom": "18.2.0",
3137
"react-native": "0.76.0",
3238
"react-native-audio-api": "workspace:*",
39+
"react-native-dotenv": "^3.4.11",
3340
"react-native-gesture-handler": "^2.20.2",
3441
"react-native-reanimated": "^3.16.1",
3542
"react-native-safe-area-context": "^4.12.0",
3643
"react-native-screens": "^3.35.0"
44+
},
45+
"expo": {
46+
"autolinking": {
47+
"exclude": [
48+
"expo-keep-awake",
49+
"expo-asset",
50+
"expo-font",
51+
"expo-constants"
52+
]
53+
}
3754
}
3855
}

apps/common-app/src/components/Select.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import React, { useState } from 'react';
22
import { ScrollView } from 'react-native-gesture-handler';
33
import { Modal, View, Text, Pressable, StyleSheet } from 'react-native';
44

apps/common-app/src/examples/AudioFile/AudioFile.tsx

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import React, { useCallback } from 'react';
2-
import { useState, useRef, useEffect, FC } from 'react';
3-
import { Container, Button } from '../../components';
1+
import React, { useCallback, useEffect, useRef, useState, FC } from 'react';
2+
import { Container, Button, Spacer } from '../../components';
3+
import * as DocumentPicker from 'expo-document-picker';
44

55
import {
66
AudioBuffer,
@@ -9,9 +9,6 @@ import {
99
} from 'react-native-audio-api';
1010
import { ActivityIndicator } from 'react-native';
1111

12-
const assetUrl =
13-
'https://audio-ssl.itunes.apple.com/apple-assets-us-std-000001/AudioPreview18/v4/9c/db/54/9cdb54b3-5c52-3063-b1ad-abe42955edb5/mzaf_520282131402737225.plus.aac.p.m4a';
14-
1512
const AudioFile: FC = () => {
1613
const [isPlaying, setIsPlaying] = useState(false);
1714

@@ -32,13 +29,31 @@ const AudioFile: FC = () => {
3229
);
3330
};
3431

35-
const fetchAudioBuffer = useCallback(async () => {
32+
const handleSetAudioSourceFromFile = async () => {
33+
try {
34+
const result = await DocumentPicker.getDocumentAsync({
35+
type: 'audio/*',
36+
multiple: false,
37+
});
38+
if (result.canceled === false) {
39+
audioBufferSourceNodeRef.current?.stop();
40+
setIsPlaying(false);
41+
setAudioBuffer(null);
42+
43+
await fetchAudioBuffer(result.assets[0].uri.replace('file://', ''));
44+
}
45+
} catch (error) {
46+
console.error('Error picking file:', error);
47+
}
48+
};
49+
50+
const fetchAudioBuffer = useCallback(async (assetUri: string) => {
3651
if (!audioContextRef.current) {
3752
audioContextRef.current = new AudioContext();
3853
}
3954

4055
const buffer =
41-
await audioContextRef.current.decodeAudioDataSource(assetUrl);
56+
await audioContextRef.current.decodeAudioDataSource(assetUri);
4257

4358
setAudioBuffer(buffer);
4459
}, []);
@@ -64,8 +79,6 @@ const AudioFile: FC = () => {
6479
audioContextRef.current = new AudioContext();
6580
}
6681

67-
fetchAudioBuffer();
68-
6982
return () => {
7083
audioContextRef.current?.close();
7184
};
@@ -75,6 +88,11 @@ const AudioFile: FC = () => {
7588
<Container centered>
7689
<Button title={isPlaying ? 'Stop' : 'Play'} onPress={handlePress} />
7790
{!audioBuffer && <ActivityIndicator color="#FFFFFF" />}
91+
<Spacer.Vertical size={20} />
92+
<Button
93+
title="Set audio source from file"
94+
onPress={handleSetAudioSourceFromFile}
95+
/>
7896
</Container>
7997
);
8098
};
-10.7 MB
Binary file not shown.

apps/fabric-example/android/app/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ android {
110110
dependencies {
111111
// The version of react-native is set by the React Native Gradle Plugin
112112
implementation("com.facebook.react:react-android")
113+
implementation project(':expo')
113114

114115
if (hermesEnabled.toBoolean()) {
115116
implementation("com.facebook.react:hermes-android")

apps/fabric-example/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
22

33
<uses-permission android:name="android.permission.INTERNET" />
4+
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
45

56
<application
67
android:name=".MainApplication"

apps/fabric-example/android/app/src/main/java/com/fabricexample/MainActivity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.fabricexample
22

3+
import expo.modules.ReactActivityDelegateWrapper
34
import com.facebook.react.ReactActivity
45
import com.facebook.react.ReactActivityDelegate
56
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
@@ -18,5 +19,5 @@ class MainActivity : ReactActivity() {
1819
* which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
1920
*/
2021
override fun createReactActivityDelegate(): ReactActivityDelegate =
21-
DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
22+
ReactActivityDelegateWrapper(this, BuildConfig.IS_NEW_ARCHITECTURE_ENABLED, DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled))
2223
}
Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,52 @@
11
package com.fabricexample
22

3+
import android.content.res.Configuration
4+
import expo.modules.ApplicationLifecycleDispatcher
5+
import expo.modules.ReactNativeHostWrapper
36
import android.app.Application
47
import com.facebook.react.PackageList
58
import com.facebook.react.ReactApplication
69
import com.facebook.react.ReactHost
710
import com.facebook.react.ReactNativeHost
811
import com.facebook.react.ReactPackage
912
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
10-
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
1113
import com.facebook.react.defaults.DefaultReactNativeHost
1214
import com.facebook.react.soloader.OpenSourceMergedSoMapping
1315
import com.facebook.soloader.SoLoader
1416

1517
class MainApplication : Application(), ReactApplication {
1618

1719
override val reactNativeHost: ReactNativeHost =
18-
object : DefaultReactNativeHost(this) {
19-
override fun getPackages(): List<ReactPackage> =
20-
PackageList(this).packages.apply {
21-
// Packages that cannot be autolinked yet can be added manually here, for example:
22-
// add(MyReactNativePackage())
23-
}
24-
25-
override fun getJSMainModuleName(): String = "index"
26-
27-
override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
20+
ReactNativeHostWrapper(this, object : DefaultReactNativeHost(this) {
21+
override fun getPackages(): List<ReactPackage> {
22+
val packages = PackageList(this).packages
23+
// Packages that cannot be autolinked yet can be added manually here, for example:
24+
// packages.add(new MyReactNativePackage());
25+
return packages
26+
}
2827

29-
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
30-
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
28+
override fun getUseDeveloperSupport(): Boolean {
29+
return BuildConfig.DEBUG;
3130
}
3231

32+
override fun getJSMainModuleName(): String = "index"
33+
override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
34+
override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
35+
})
36+
3337
override val reactHost: ReactHost
34-
get() = getDefaultReactHost(applicationContext, reactNativeHost)
38+
get() = ReactNativeHostWrapper.createReactHost(applicationContext, reactNativeHost)
3539

3640
override fun onCreate() {
3741
super.onCreate()
3842
SoLoader.init(this, OpenSourceMergedSoMapping)
39-
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
40-
// If you opted-in for the New Architecture, we load the native entry point for this app.
41-
load()
42-
}
43+
load()
44+
45+
ApplicationLifecycleDispatcher.onApplicationCreate(this)
46+
}
47+
48+
override fun onConfigurationChanged(newConfig: Configuration) {
49+
super.onConfigurationChanged(newConfig)
50+
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig)
4351
}
4452
}

apps/fabric-example/android/gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ android.useAndroidX=true
2525
# Use this property to specify which architecture you want to build.
2626
# You can also override it from the CLI using
2727
# ./gradlew <task> -PreactNativeArchitectures=x86_64
28-
reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
28+
reactNativeArchitectures=armeabi-v7a,arm64-v8a
2929

3030
# Use this property to enable support to the new architecture.
3131
# This will allow you to use TurboModules and the Fabric render in

apps/fabric-example/android/settings.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autoli
44
rootProject.name = 'FabricExample'
55
include ':app'
66
includeBuild('../node_modules/@react-native/gradle-plugin')
7+
8+
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
9+
useExpoModules()

0 commit comments

Comments
 (0)