Skip to content

Repository files navigation

NativeScript plugin to play and record audio files for Android and iOS.

npm


Installation

NativeScript 7+:

npm install nativescript-audio

NativeScript Version prior to 7:

tns plugin add nativescript-audio@5.1.1


Android Native Classes

iOS Native Classes

Permissions

iOS

You will need to grant permissions on iOS to allow the device to access the microphone if you are using the recording function. If you don't, your app may crash on device and/or your app might be rejected during Apple's review routine. To do this, add this key to your app/App_Resources/iOS/Info.plist file:

<key>NSMicrophoneUsageDescription</key>
<string>Recording Practice Sessions</string>

Android

If you are going to use the recorder capability for Android, you need to add the RECORD_AUDIO permission to your AndroidManifest.xml file located in App_Resources.

 <uses-permissionandroid:name="android.permission.RECORD_AUDIO"/>

Usage

TypeScript Example

import{TNSPlayer}from'nativescript-audio';exportclassYourClass{private_player: TNSPlayer;constructor(){this._player=newTNSPlayer();// You can pass a duration hint to control the behavior of other application that may// be holding audio focus.// For example: new TNSPlayer(AudioFocusDurationHint.AUDIOFOCUS_GAIN_TRANSIENT);// Then when you play a song, the previous owner of the// audio focus will stop. When your song stops// the previous holder will resume.this._player.debug=true;// set true to enable TNSPlayer console logs for debugging.this._player.initFromFile({audioFile: '~/assets/song.mp3',// ~ = app directoryloop: false,completeCallback: this._trackComplete.bind(this),errorCallback: this._trackError.bind(this)}).then(()=>{this._player.getAudioTrackDuration().then(duration=>{// iOS: duration is in seconds// Android: duration is in millisecondsconsole.log(`song duration:`,duration);});});}publictogglePlay(){if(this._player.isAudioPlaying()){this._player.pause();}else{this._player.play();}}private_trackComplete(args: any){console.log('reference back to player:',args.player);// iOS only: flag indicating if completed succesfullyconsole.log('whether song play completed successfully:',args.flag);}private_trackError(args: any){console.log('reference back to player:',args.player);console.log('the error:',args.error);// Android only: extra detail on errorconsole.log('extra info on the error:',args.extra);}// This is an example method for watching audio meters and converting the values from Android's arbitrary // value to something close to dB. iOS reports values from -120 to 0, android reports values from 0 to about 37000.// The below method converts the values to db as close as I could figure out. You can tweak the .1 value to your discretion.// I am basically converting these numbers to something close to a percentage value. My handle Meter UI method// converts that value to a value I can use to pulse a circle bigger and smaller, representing your audio level. private_initMeter(){this._resetMeter();this._meterInterval=this._win.setInterval(()=>{this.audioMeter=this._recorder.getMeters();if(isIOS){this.handleMeterUI(this.audioMeter+200)}else{letdb=(20*Math.log10(parseInt(this.audioMeter)/.1));letpercentage=db+85;this.handleMeterUI(percentage)}},150);}handleMeterUI(percentage){letscale=percentage/100;functionmap_range(value,in_low,in_high,out_low,out_high){returnout_low+(out_high-out_low)*(value-in_low)/(in_high-in_low);}letlerpScale=map_range(scale,1.2,1.9,0.1,2.1)if(scale>0){this.levelMeterCircleUI.animate({scale: {x: lerpScale,y: lerpScale},duration: 100}).then(()=>{}).catch(()=>{})}if(lerpScale>2.2){this.levelBgColor='rgba(255, 0, 0, 1)';}else{this.levelBgColor='rgb(0, 183, 0)';}}}

Javascript Example:

constaudio=require('nativescript-audio');constplayer=newaudio.TNSPlayer();constplayerOptions={audioFile: 'http://some/audio/file.mp3',loop: false,completeCallback: function(){console.log('finished playing');},errorCallback: function(errorObject){console.log(JSON.stringify(errorObject));},infoCallback: function(args){console.log(JSON.stringify(args));}};player.playFromUrl(playerOptions).then(res=>{console.log(res);}).catch(err=>{console.log('something went wrong...',err);});

API

Recorder

TNSRecorder Methods

MethodDescription
TNSRecorder.CAN_RECORD(): boolean - static methodDetermine if ready to record.
start(options: AudioRecorderOptions): Promise<void>Start recording to file.
stop(): Promise<void>Stop recording.
pause(): Promise<void>Pause recording.
resume(): Promise<void>Resume recording.
dispose(): Promise<void>Free up system resources when done with recorder.
getMeters(channel?: number): numberReturns the amplitude of the input.
isRecording(): boolean - iOS OnlyReturns true if recorder is actively recording.
requestRecordPermission(): Promise<void>Android Only Resolves the promise is user grants the permission.
hasRecordPermission(): booleanAndroid Only Returns true if RECORD_AUDIO permission has been granted.

TNSRecorder Instance Properties

PropertyDescription
iosGet the native AVAudioRecorder class instance.
androidGet the native MediaRecorder class instance.
debugSet true to enable debugging console logs (default false).

TNSRecorder AudioRecorderOptions

PropertyTypeDescription
filenamestringGets or sets the recorded file name.
sourceintAndroid Only Sets the source for recording. Learn more here https://developer.android.com/reference/android/media/MediaRecorder.AudioSource
maxDurationintGets or set the max duration of the recording session. Input in milliseconds, which is Android's format. Will be converted appropriately for iOS.
meteringbooleanEnables metering. This will allow you to inspect the audio level by calling the record instance's getMeters ,method. This will return dB on iOS, but an arbitrary amplitude number for Android. See the metering example for a way to convert the output to something resembling dB on Android.
formatint or enumThe Audio format to record in. On Android, use these Enums: https://developer.android.com/reference/android/media/AudioFormat#ENCODING_PCM_16BIT On ios, use these format options: https://developer.apple.com/documentation/coreaudiotypes/1572096-audio_format_identifiers
channelsintNumber of channels to record (mono, st)
sampleRateintThe sample rate to record in. Default: 44100
bitRateintAndroid Only The bitrate to record in. iOS automatically calculates based on iosAudioQuality flag. Default: 128000
encoderint or enumAndroid Only Use https://developer.android.com/reference/android/media/MediaRecorder.AudioEncoder#AAC
iosAudioQualitystringios uses AVAudioQuality to determine encoder and bitrate. Accepts Min, Low, Medium, High, Max https://developer.apple.com/documentation/avfaudio/avaudioquality
errorCallbackfunctionGets or sets the callback when an error occurs with the media recorder. Returns An object containing the native values for the error callback.
infoCallbackfunctionGets or sets the callback to be invoked to communicate some info and/or warning about the media or its playback. Returns An object containing the native values for the info callback.

Player

TNSPlayer Methods

MethodDescription
initFromFile(options: AudioPlayerOptions): PromiseInitialize player instance with a file without auto-playing.
playFromFile(options: AudioPlayerOptions): PromiseAuto-play from a file.
initFromUrl(options: AudioPlayerOptions): PromiseInitialize player instance from a url without auto-playing.
playFromUrl(options: AudioPlayerOptions): PromiseAuto-play from a url.
pause(): Promise<boolean>Pause playback.
resume(): voidResume playback.
seekTo(time:number): Promise<boolean>Seek to position of track (in seconds).
dispose(): Promise<boolean>Free up resources when done playing audio.
isAudioPlaying(): booleanDetermine if player is playing.
getAudioTrackDuration(): Promise<string>Duration of media file assigned to the player.
playAtTime(time: number): void - iOS OnlyPlay audio track at specific time of duration.
changePlayerSpeed(speed: number): void - On Android Only API 23+Change the playback speed of the media player.

TNSPlayer Instance Properties

PropertyDescription
iosGet the native ios AVAudioPlayer instance.
androidGet the native android MediaPlayer instance.
debug: booleanSet true to enable debugging console logs (default false).
currentTime: numberGet the current time in the media file's duration.
volume: numberGet/Set the player volume. Value range from 0 to 1.

License

MIT

Demo App

  • fork/clone the repository
  • cd into the src directory
  • execute npm run demo.android or npm run demo.ios (scripts are located in the scripts of the package.json in the src directory if you are curious)

About

🎤 NativeScript plugin to record and play audio 🎵

Topics

Resources

Stars

151 stars

Watchers

8 watching

Forks

Releases

Packages

Used by

Contributors

Languages