[TIMOB-2122] Android: Implement Video Recording
GitHub Issue | n/a |
---|---|
Type | New Feature |
Priority | Medium |
Status | Closed |
Resolution | Fixed |
Resolution Date | 2016-04-26T04:57:53.000+0000 |
Affected Version/s | n/a |
Fix Version/s | Release 6.0.0, Release 5.4.0 |
Components | Android |
Labels | dr-list, parity, supportTeam, tbs-1.8.0 |
Reporter | Don Thorp |
Assignee | Ashraf Abu |
Created | 2011-04-15T03:11:06.000+0000 |
Updated | 2016-07-12T21:50:53.000+0000 |
Description
Comments
- Jon Alter 2011-07-21
Associated Helpdesk Ticket
http://appc.me/c/APP-632317 - ankur garha 2013-06-07 Is this feature still implemented for android or not???
- Dan Peleg 2014-04-21 Solved here: [https://github.com/appcelerator/titanium_mobile/pull/5634]
- Johan Chaves 2014-08-19 Hi, when is this going to be integrated?
- Michael Gangolf 2016-03-15 @danpe iOS has startVideoCapture( ) and stopVideoCapture(). So renaming the android methods startRecording/stopRecording would help to add this to android
- Michael Gangolf 2016-04-09
Started to work on a new PR: https://github.com/appcelerator/titanium_mobile/pull/7929
Not ready yet but it's already working on a Nexus 4 (5.1.1) with native camera (with overlays and maxDuration) and the intent version!
*Example:*
!http://www.migaweb.de/ti_video_example.png! Added documentation and extended the examplevar isRecording = false; var isPhoto = false; // photo or video mode var win = Ti.UI.createWindow({ backgroundColor: "#fff" }); var btn_cam1 = Ti.UI.createButton({ bottom: 10, title: "CAM INTENT" }) var btn_cam2 = Ti.UI.createButton({ bottom: 50, title: "CAM OVERLAY REAR", id: "cam_rear" }) var btn_cam3 = Ti.UI.createButton({ bottom: 90, title: "CAM OVERLAY FRONT", id: "cam_front" }) var btn_cam4 = Ti.UI.createButton({ bottom: 130, title: "PHOTO REAR", id: "photo_rear" }) var btn_cam5 = Ti.UI.createButton({ bottom: 170, title: "PHOTO FRONT", id: "photo_front" }) var btnCamera = Ti.UI.createButton({ title: 'RECORD', bottom: 10 }); var btnCameraClose = Ti.UI.createButton({ title: 'CLOSE', top: 10 }); var overlay = Ti.UI.createView({ top: 0, right: 0, bottom: 0, left: 0 }); var movie = Titanium.Media.createVideoPlayer({ movieControlStyle: Titanium.Media.VIDEO_CONTROL_EMBEDDED, top: 0, height: 200, width: 200, backgroundColor: "#000", autoplay:false }); overlay.add(btnCamera); overlay.add(btnCameraClose); btnCameraClose.addEventListener('click', function(e) { Titanium.Media.hideCamera(); }); btnCamera.addEventListener('click', function(e) { if (isPhoto){ // photo mode Titanium.Media.takePicture(); } else { // video mode if (!isRecording) { Titanium.Media.startVideoCapture(); isRecording = true; btnCamera.title = "STOP"; } else { Titanium.Media.stopVideoCapture(); } } }); function onClickCam(e) { // intent Ti.Media.showCamera({ autohide: false, animated: false, allowEditing: false, saveToPhotoGallery: true, success: function(event) { movie.url = event.media.nativePath; }, cancel: function(event) { console.log("error"); }, error: function(error) { alert('error'); }, mediaTypes: [Titanium.Media.MEDIA_TYPE_VIDEO], videoMaximumDuration: 5000, videoQuality: Titanium.Media.QUALITY_HIGH }); } function onClickCam2(e) { // native camera var which = Ti.Media.CAMERA_REAR; var type = Titanium.Media.MEDIA_TYPE_VIDEO; var autohide = false; isPhoto = false; if (e.source.id == "cam_front") { which = Ti.Media.CAMERA_FRONT; } if (e.source.id=="photo_front") { which = Ti.Media.CAMERA_FRONT; type = Ti.Media.MEDIA_TYPE_PHOTO; isPhoto = true; autohide = true; } if (e.source.id=="photo_rear") { type = Ti.Media.MEDIA_TYPE_PHOTO; isPhoto = true; autohide = true; } console.log(type + " " + which); Ti.Media.showCamera({ overlay: overlay, autohide: autohide, animated: false, allowEditing: false, saveToPhotoGallery: true, whichCamera: which, success: function(event) { if (!isPhoto) movie.url = event.media.nativePath; isRecording = false; btnCamera.title = "RECORD"; }, cancel: function(event) { console.log("error"); }, error: function(error) { alert('error'); }, mediaTypes: [type], videoMaximumDuration: 5000, videoQuality: Titanium.Media.QUALITY_HIGH }); } btn_cam1.addEventListener("click", onClickCam); btn_cam2.addEventListener("click", onClickCam2); btn_cam3.addEventListener("click", onClickCam2); btn_cam4.addEventListener("click", onClickCam2); btn_cam5.addEventListener("click", onClickCam2); win.add(btn_cam1); win.add(btn_cam2); win.add(btn_cam3); win.add(btn_cam4); win.add(btn_cam5); win.add(movie); win.open();
- Michael Gangolf 2016-04-10 Tested on: * Nexus 4 (5.1.1) * HTC A9 (6.0.1) * Samsung Galaxy S2 (4.2.2)
- Ashraf Abu 2016-04-26 PR by [~michael] https://github.com/appcelerator/titanium_mobile/pull/7929 Merged. Additional PR for minor code formatting: https://github.com/appcelerator/titanium_mobile/pull/7965
- Ashraf Abu 2016-04-26
Additional note: For android 6.0, for the Video to record sound as well, you would need to grant the permission
android.permission.RECORD_AUDIO
- Ashraf Abu 2016-04-27
Test app code including permission requests that is needed in Android 6.0:-
var isRecording = false; var isPhoto = false; // photo or video mode var win = Ti.UI.createWindow({ backgroundColor: "#fff" }); var btn_cam1 = Ti.UI.createButton({ bottom: 10, title: "CAM INTENT" }); var btn_cam2 = Ti.UI.createButton({ bottom: 50, title: "CAM OVERLAY REAR", id: "cam_rear" }); var btn_cam3 = Ti.UI.createButton({ bottom: 90, title: "CAM OVERLAY FRONT", id: "cam_front" }); var btn_cam4 = Ti.UI.createButton({ bottom: 130, title: "PHOTO REAR", id: "photo_rear" }); var btn_cam5 = Ti.UI.createButton({ bottom: 170, title: "PHOTO FRONT", id: "photo_front" }); var btnCamera = Ti.UI.createButton({ title: 'RECORD', bottom: 10 }); var btnCameraClose = Ti.UI.createButton({ title: 'CLOSE', top: 10 }); var overlay = Ti.UI.createView({ top: 0, right: 0, bottom: 0, left: 0 }); var movie = Titanium.Media.createVideoPlayer({ movieControlStyle: Titanium.Media.VIDEO_CONTROL_EMBEDDED, top: 0, height: 200, width: 200, backgroundColor: "#000", autoplay:false }); overlay.add(btnCamera); overlay.add(btnCameraClose); btnCameraClose.addEventListener('click', function(e) { Titanium.Media.hideCamera(); }); btnCamera.addEventListener('click', function(e) { if (isPhoto){ // photo mode Titanium.Media.takePicture(); } else { // video mode if (!isRecording) { Titanium.Media.startVideoCapture(); isRecording = true; btnCamera.title = "STOP"; } else { Titanium.Media.stopVideoCapture(); } } }); function onClickCam(e) { // intent Ti.Media.showCamera({ autohide: false, animated: false, allowEditing: false, saveToPhotoGallery: true, success: function(event) { movie.url = event.media.nativePath; }, cancel: function(event) { console.log("error"); }, error: function(error) { alert('error'); }, mediaTypes: [Titanium.Media.MEDIA_TYPE_VIDEO], videoMaximumDuration: 5000, videoQuality: Titanium.Media.QUALITY_HIGH }); } function onClickCam2(e) { // native camera var which = Ti.Media.CAMERA_REAR; var type = Titanium.Media.MEDIA_TYPE_VIDEO; var autohide = false; isPhoto = false; if (e.source.id == "cam_front") { which = Ti.Media.CAMERA_FRONT; } if (e.source.id=="photo_front") { which = Ti.Media.CAMERA_FRONT; type = Ti.Media.MEDIA_TYPE_PHOTO; isPhoto = true; autohide = true; } if (e.source.id=="photo_rear") { type = Ti.Media.MEDIA_TYPE_PHOTO; isPhoto = true; autohide = true; } console.log(type + " " + which); Ti.Media.showCamera({ overlay: overlay, autohide: autohide, animated: false, allowEditing: false, saveToPhotoGallery: true, whichCamera: which, success: function(event) { if (!isPhoto) movie.url = event.media.nativePath; isRecording = false; btnCamera.title = "RECORD"; }, cancel: function(event) { console.log("error"); }, error: function(error) { alert('error'); }, mediaTypes: [type], videoMaximumDuration: 5000, videoQuality: Titanium.Media.QUALITY_HIGH }); } btn_cam1.addEventListener("click", onClickCam); btn_cam2.addEventListener("click", onClickCam2); btn_cam3.addEventListener("click", onClickCam2); btn_cam4.addEventListener("click", onClickCam2); btn_cam5.addEventListener("click", onClickCam2); win.add(btn_cam1); win.add(btn_cam2); win.add(btn_cam3); win.add(btn_cam4); win.add(btn_cam5); win.add(movie); win.open(); var permissionsToRequest = []; var audioPermission = "android.permission.RECORD_AUDIO"; var hasAudioPerm = Ti.Android.hasPermission(audioPermission); if (!hasAudioPerm) { permissionsToRequest.push(audioPermission); } var cameraPermission = "android.permission.CAMERA"; var hasCameraPerm = Ti.Android.hasPermission(cameraPermission); if (!hasCameraPerm) { permissionsToRequest.push(cameraPermission); } var storagePermission = "android.permission.READ_EXTERNAL_STORAGE"; var hasStoragePerm = Ti.Android.hasPermission(storagePermission); if (!hasStoragePerm) { permissionsToRequest.push(storagePermission); } if (permissionsToRequest.length > 0) { Ti.Android.requestPermissions(permissionsToRequest, function(e) { if (e.success) { Ti.API.info("SUCCESS"); } else { Ti.API.info("ERROR: " + e.error); } }); }
- Lokesh Choudhary 2016-07-12 Verified the implementation. Video recording works as expected. Closing. Environment: Appc Studio : 4.7.0.201607111053 Ti SDK : 5.4.0.v20160712013704 Ti CLI : 5.0.9 Alloy : 1.9.1 MAC El Capitan : 10.11.5 Appc NPM : 4.2.8-1 Appc CLI : 5.4.0-31 Node: 4.4.4 Nexus 6 - Android 6.0.1