I am building an audio player for my react native expo project. I am using expo-av to play the sound that I am pulling from my AWS s3 bucket. I am using expo SDK 44. Everything works fine on Android, but I am receiving an error on iOS:
[Unhandled promise rejection: Error: This media format is not supported. - The AVPlayerItem instance has failed with the error code -11828 and domain "AVFoundationErrorDomain".]
-I have tried this with both .mp3 and .m4a files
-everything works on android
-local files work on iOS (require('./myaudiotrack.mp3') but not from my bucket
-this seems to be a problem with the URL that is being returned from the s3bucket and it is working with a URL with an audio file extension.
async function PlayPause() {
await Audio.setAudioModeAsync({
staysActiveInBackground: true,
interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
shouldDuckAndroid: false,
playThroughEarpieceAndroid: false,
allowsRecordingIOS: false,
interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
playsInSilentModeIOS: true,
});
const { sound } = await Audio.Sound.createAsync(
{uri: AudioUri}, <------ this works on android, not ios
//require('../assets/zelda.mp3'), <--this works
{
shouldPlay: true,
rate: 1.0,
shouldCorrectPitch: false,
volume: 1.0,
isMuted: false,
isLooping: false,
},
);
setSound(sound);
await sound.playAsync();
}
I was able to fix the problem by declaring a file type using contentType: "audio/mp3" during the bucket upload.
Related
Im working on an app that records audio using expo and makes use of the metering value
I was using version 10, and have just updated to version 12,
However after doing so, the metering value is always undefined, despite setting isMeteringEnabled to true, and it should have already been true from that preset anyway
Im running this on web, have not yet tested on native
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
interruptionModeIOS: 1,
playsInSilentModeIOS: true,
shouldDuckAndroid: false,
interruptionModeAndroid: 1,
playThroughEarpieceAndroid: false,
staysActiveInBackground: true
})
const recording = new Audio.Recording()
await recording.prepareToRecordAsync({
...Audio.RecordingOptionsPresets.HIGH_QUALITY,
isMeteringEnabled: true
})
recording.setOnRecordingStatusUpdate((status: RecordingStatus) => {
console.log(status.metering) // undefined
})
var path = RNFetchBlob.fs.dirs.DocumentDir
RNFetchBlob
.config({
path: toFile,
addAndroidDownloads: {
useDownloadManager: true,
mime: 'text/plain',
description: 'Downloading...',
notification: false
}
})
.fetch('GET', fromUrl)
.progress((received, total) => {
})
I am using the above code for downloading files in the react-native. This is working fine in IOS. But not working with android.
I also tried
var path = RNFetchBlob.fs.dirs.DownloadDir
I also check with permission in Manifest
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
But nothing worked so Please let me know how can i resolve it. In the android and download files in the com.appname folder.
Thanks
I am using the audio component of Expo and need to export it in MP3 format。encountering such an error Error Domain=NSOSStatusErrorDomain Code=1718449215 "(null)"]
This is my code
const recording = new Audio.Recording();
await recording.prepareToRecordAsync({
isMeteringEnabled: true,
android: {
extension: '.m4a',
outputFormat: RECORDING_OPTION_ANDROID_OUTPUT_FORMAT_MPEG_4,
audioEncoder: RECORDING_OPTION_ANDROID_AUDIO_ENCODER_AAC,
sampleRate: 44100,
numberOfChannels: 2,
bitRate: 128000,
},
ios: {
extension: '.mp3',
outputFormat: Audio.RECORDING_OPTION_IOS_OUTPUT_FORMAT_MPEGLAYER3,
audioQuality: Audio.RECORDING_OPTION_IOS_AUDIO_QUALITY_MEDIUM,
sampleRate: 44100,
numberOfChannels: 2,
bitRate: 128000,
linearPCMBitDepth: 16,
linearPCMIsBigEndian: false,
linearPCMIsFloat: false,
},
})
Based on this documentation (found this link via expo docs here) iOS does not support MP3 recording.
...neither MP3 nor AAC recording is available. This is due to the high CPU overhead, and consequent battery drain, of these formats.
If you're curious about the original error, you can find more info about the corresponding native code which may have produced this error here
I am using Expo sdk 37.0.1 & asking for camera and gallery permission. It's working in local expo device & emulator but when I build APK installed in real device it's always denied. Below is the code to get/set permission.
const resultCamera = await Permissions.askAsync(Permissions.CAMERA);
I also added permission in app.json file which seems to be correct as per documentation of expo itself which is needed for standalone app.
https://docs.expo.io/versions/latest/sdk/permissions/#android-permissions-equivalents-inside-appjson
App.json code as below
"android": {
"versionCode": 9,
"permissions": [
"CAMERA",
"READ_INTERNAL_STORAGE",
"WRITE_INTERNAL_STORAGE",
"READ_EXTERNAL_STORAGE",
"WRITE_EXTERNAL_STORAGE"
]
},
I also log the output of standalone app of const resultCamera = await Permissions.askAsync(Permissions.CAMERA)
"resultCamera": {
"status": "denied",
"expires": "never",
"canAskAgain": false,
"granted": false,
"permissions": {
"camera": {
"granted": false,
"status": "denied",
"canAskAgain": false,
"expires": "never"
}
}
}
My sdk package of react native is as below
"react-native": "https://github.com/expo/react-native/archive/sdk-37.0.1.tar.gz",
How can I resolve this issue?
I have encountered a similar problem with the expo-av microphone permissions. In the expo client the permissions work flawlessly but when I had to eject to use some native modules the permissions got wacky. On Android, the canAskAgain permission always returned false (I haven't got around to ios).I found a workaround for my issue that may be useful for you.
Triggering a permission request hinged on the permission not being granted and the ability to ask again. But expo-av defaults permissions.canAskAgain to false so I did this:
async function getPermissions(){
let permissions = await Audio.getPermissionsAsync();
console.log(permissions)
setCanUseMic(permissions.granted);
if(!permissions.granted){
console.log('Requesting mic permissions')
try{
await Audio.requestPermissionsAsync();
// update permissions
permissions = await Audio.getPermissionsAsync();
setCanUseMic(permissions.granted);
}catch(err){
if(!permission.canAskAgain){
console.log('Unable to ask again for mic permissions')
// use an alert to tell user to go to settings to enable mic permissions
}
}
}
}
Instead of checking permissions.canAskAgain, I simply request the permission. So far, it works out fine
I'm currently trying to write some automated tests for our cordova app written in Angular.
My current setup is the following:
Versions:
appium: 1.7.2
wdio-appium-service: 0.2.3
webdriverio: 4.11.0
wdio.conf.js
exports.config = {
port: 4723,
logLevel: 'error',
capabilities: [{
platformName: 'Android',
platformVersion: '8.1',
deviceName: 'any',
app: '../cordova_app/platforms/android/app/build/outputs/apk/debug/app-debug.apk',
autoWebview: true,
autoGrantPermissions: true
}],
// specs: ['./tests/spec/**/*.js'],
specs: ['./tests/spec/login.js'],
services: ['appium'],
reporters: ['spec'],
framework: 'jasmine',
jasmineNodeOpts: {
defaultTimeoutInterval: 90000
}
}
tests/spec/login.js
describe('Language and market choosing process', () => {
beforeEach(() => {
browser.timeouts('implicit', 2000);
});
afterEach(() => {
browser.reload();
});
it('should go through login process', () => {
const selectCountryBtn = $('.fsr-login__market-chooser');
selectCountryBtn.click();
// everything works so far
browser.localStorage('POST', {key: 'test', value: 'test123'});
// Failed: unknown error: call function result missing 'value'
});
});
When I run this test on my Android 8.1 emulator, the test crashes as soon as it reaches the localstorage part with the error:
Failed: unknown error: call function result missing "value"
Error: An unknown server-side error occurred while processing the command.
at localStorage("POST", [object Object]) - index.js:316:3
The localStorage API of WebdriverIO is described here
What am I doing wrong?
I agree that localStorage manipulation is a tricky endeavour to tackle, especially cross-browser, cross-platform, etc. When dealing with application cookies, or local storage, I default to using plain JS commands to achieve my goal.
As such, I would recommend you try the browser.execute() command to manipulate the browser's local storage:
browser.execute("localStorage.setItem('socialMediaRuinsTheWorld', true)");
or
browser.execute((keyName, keyValue) => {
localStorage.setItem(keyName, keyValue);
}, "testing", "theLocalStorage");
Outcome:
Appium API doesn't offer function localStorage.
I think this is your problem. Also if you use 3.4 version, check Appium section, not only Protocol. Native apps don't have same localStorage as browser and you can't access to it easily.