hi everyone,
wanted to ask if i can record on android? i'm using Titanium mobile sdk 1.6
checked kitchensink, checked the soun_record.js but seems as if it is only for iOS and not for android?
var recorder = Titanium.Media.createAudioRecorder();gives me error: cannot find function createAudioRecorder in object [Ti.Media]....
can i record in android with audiorecorder? or any other way to record in android?
will be very grateful for your help and responses...
8 Answers
Accepted Answer
Now recording is possible on Android, natively, without Intents. We just released the Audio Recorder Titanium Module for Android. You can see more details on Codeboxed Titanium Audio Recorder Module Follow us on Twitter: @codeboxed for more updates.
Blog post came out yesterday Launching Activities and Using Content URIs in Android
Apparently, there's a demo coming soon to show how to do this with Android 'intents'.
problem is currently there in no way in Android to get the voice recording file name from the URI -- short of coding up a module. Would have been to include this in the URI work already implemented.
Forgive my inability to update the GIT hub, but here's a modified version of the 'KitchenSink/Resources/examples/sound_record.js' (as of 7/27/11) that uses the above example and fits into the rest of the window's design. One problem I can't get around is that I think the sample rate is inaccurate in the recorded resource, so when played back it sounds like it's coming out at half the speed.
Too many lines, you'll need to copy from the GIT version of sound_record.js to replace my deleted '...' sections.
var win = Titanium.UI.currentWindow; var file; var timer; var sound; var label = Titanium.UI.createLabel({ text:'', top:150, color:'#999', textAlign:'center', width:'auto', height:'auto' }); win.add(label); function lineTypeToStr() { ... } var linetype = Titanium.UI.createLabel({ text: "audio line type: "+lineTypeToStr(), bottom:20, color:'#999', textAlign:'center', width:'auto', height:'auto' }); win.add(linetype); var volume = Titanium.UI.createLabel({ text: "volume: "+Ti.Media.volume, bottom:50, color:'#999', textAlign:'center', width:'auto', height:'auto' }); win.add(volume); Ti.Media.addEventListener('linechange',function(e) { linetype.text = "audio line type: "+lineTypeToStr(); }); Ti.Media.addEventListener('volume',function(e) { volume.text = "volume: "+e.volume; }); var duration = 0; function showLevels() { var peak = Ti.Media.peakMicrophonePower; var avg = Ti.Media.averageMicrophonePower; duration++; label.text = 'duration: '+duration+' seconds\npeak power: '+peak+'\navg power: '+avg; } var b1 = Titanium.UI.createButton({ title:'Start Recording', width:200, height:40, top:20 }); var isAndroid = (Titanium.Platform.name != 'iPhone OS'); if (!isAndroid) { Titanium.Media.audioSessionMode = Ti.Media.AUDIO_SESSION_MODE_PLAY_AND_RECORD; var recording = Ti.Media.createAudioRecorder(); // default compression is Ti.Media.AUDIO_FORMAT_LINEAR_PCM // default format is Ti.Media.AUDIO_FILEFORMAT_CAF // this will give us a wave file with µLaw compression which // is a generally small size and suitable for telephony recording // for high end quality, you'll want LINEAR PCM - however, that // will result in uncompressed audio and will be very large in size recording.compression = Ti.Media.AUDIO_FORMAT_ULAW; recording.format = Ti.Media.AUDIO_FILEFORMAT_WAVE; Ti.Media.addEventListener('recordinginput', function(e) { Ti.API.info('Input availability changed: '+e.available); if (!e.available && recording.recording) { b1.fireEvent('click', {}); } }); b1.addEventListener('click', function() { ... }); var pause = Titanium.UI.createButton({ title:'Pause recording', width:200, height:40, top:80 }); win.add(pause); pause.hide(); pause.addEventListener('click', function() { ... }); var switchLabel = Titanium.UI.createLabel({ ... }); var switcher = Titanium.UI.createSwitch({ value:false, bottom:80 }); switcher.addEventListener('change',function(e) { if (!switcher.value) { recording.compression = Ti.Media.AUDIO_FORMAT_ULAW; } else { recording.compression = Ti.Media.AUDIO_FORMAT_LINEAR_PCM; } }); win.add(switchLabel); win.add(switcher); } else { // code from http://developer.appcelerator.com/blog/2011/02/launching-activities-and-using-content-uris-in-android.html // const value grabbed from // http://developer.android.com/reference/android/provider/MediaStore.Audio.Media.html#RECORD_SOUND_ACTION var RECORD_SOUND_ACTION = "android.provider.MediaStore.RECORD_SOUND"; b1.addEventListener('click', function() { var intent = Titanium.Android.createIntent({ action: RECORD_SOUND_ACTION }); Titanium.Android.currentActivity.startActivityForResult(intent, function(e) { if (e.error) { Ti.API.info('Error: '+e.error); Titanium.UI.createAlertDialog({ title:'Error!', message:e.error }).show(); } else { if (e.resultCode === Titanium.Android.RESULT_OK) { file = e.intent.data; b2.show(); } else { Ti.API.info('Cancel/Error? Result code:'+e.resultCode); Titanium.UI.createAlertDialog({ title:'Error!', message: 'Canceled/Error? Result code: ' + e.resultCode }).show(); return; } } }); //end start intent }); } win.add(b1); var b2 = Titanium.UI.createButton({ title:'Playback Recording', width:200, height:40, top:80 }); win.add(b2); b2.hide(); b2.addEventListener('click', function() { if (sound && sound.playing) { sound.stop(); sound.release(); sound = null; b2.title = 'Playback Recording'; } else { if (!isAndroid) { Ti.API.info("recording file size: "+file.size); sound = Titanium.Media.createSound({sound:file}); } else { Ti.API.info("recording file: "+file); sound = Titanium.Media.createSound({url:file}); } sound.addEventListener('complete', function() { b2.title = 'Playback Recording'; }); sound.play(); b2.title = 'Stop Playback'; } });
After work on this a little more, I found it difficult to manipulate files that were captured via the audio recorder, not to mention the fact that they get added into he media player's library. Instead, I found these steps necessary to build your own audio capture module in android...
- Follow appcelerator's module guide
- Copy a short example of an audio recorder into your new module.
- Copy your module locally and run it on android.
Not ideal (because it does involve some grease work in the android API), but it seems to be working after a day of frustration. Seems odd that this functionality didn't make it into an earlier cut of the SDK.
Hope this helps for others.
Codeboxed will release a module tomorrow that will handle audio recording on Android. No more Android VU meters and platform specific components. Follow us on twitter: @codeboxed or here www.codeboxed.com
Your Answer
Think you can help? Login to answer this question!