I've got live camera input working both on the desktop (MacBook Pro) and iOS (iPhone4), but I can't get anything out of either of my Android phones (LG Optimus and Samsung Galaxy Nexus). Here's my script (attach it to a plane with a RenderTexture) Code (csharp): #pragma strict private var devices : WebCamDevice[]; public var deviceName : String; private var wct : WebCamTexture; private var resultString : String; function Start() { yield Application.RequestUserAuthorization (UserAuthorization.WebCam | UserAuthorization.Microphone); if (Application.HasUserAuthorization(UserAuthorization.WebCam | UserAuthorization.Microphone)) { devices = WebCamTexture.devices; deviceName = devices[0].name; wct = new WebCamTexture(deviceName, 640, 480, 30); renderer.material.mainTexture = wct; wct.Play(); resultString = "no problems"; } else { resultString = "no permission!"; } } function OnGUI() { for (var i = 0; i < devices.length; i++) { GUI.Box(Rect(100, 100+(i*25), 300, 25),devices[i].name); } GUI.Box(Rect(100, 100+(i*25), 400, 25),resultString); } Would appreciate any advice or pointers. (also posted on Unity Answers http://answers.unity3d.com/questions/217940/)
BUMP. Come on. Someone must have some ideas or advice. Or is no one working with cameras on Android? Here's my latest test script, and a jpg of the results. Code (csharp): #pragma strict private var devices : WebCamDevice[]; private var deviceName : String; private var wct : WebCamTexture; private var resultString : String; private var update: boolean; private var data : Color32[]; function Start() { yield Application.RequestUserAuthorization (UserAuthorization.WebCam | UserAuthorization.Microphone); if (Application.HasUserAuthorization(UserAuthorization.WebCam | UserAuthorization.Microphone)) { devices = WebCamTexture.devices; deviceName = devices[0].name; wct = new WebCamTexture(deviceName, 640, 360, 15); renderer.material.mainTexture = wct; wct.Play(); resultString = "no problems"; } else { resultString = "no permission!"; } data = new Color32[wct.width * wct.height]; } function Update() { if (wct) { if (wct.didUpdateThisFrame) { update = true; wct.GetPixels32 (data); } else { update = false; } } } function OnGUI() { for (var i = 0; i < devices.length; i++) { GUI.Box(Rect(100, 100+(i*25), 200, 25),"NAME: "+devices[i].name); GUI.Box(Rect(300, 100+(i*25), 200, 25),"FRONT FACING? "+devices[i].isFrontFacing); } GUI.Box(Rect(100, 100+(i*25), 200, 25),"OPENED? "+resultString); GUI.Box(Rect(300, 100+(i*25), 200, 25),"PLAYING? "+wct.isPlaying); GUI.Box(Rect(100, 125+(i*25), 200, 25),"UPDATED? "+update); }
You completely ignored the only person who gave you advice, and it was good advice. Until you answer them, why would anyone suggest anything else? Did you update the manifest?
OK, fair enough. I did look at the manifest and couldn't find anything wrong, but maybe I'm missing something. Here it is: Code (csharp): <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="edu.usc.perrywct" android:versionName="1.0" android:versionCode="1"> <supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" /> <application android:icon="@drawable/app_icon" android:label="@string/app_name" android:debuggable="false"> <activity android:name="com.unity3d.player.UnityPlayerProxyActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="reverseLandscape"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="reverseLandscape"> </activity> <activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="reverseLandscape"> <meta-data android:name="android.app.lib_name" android:value="unity" /> <meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="false" /> </activity> <activity android:name="com.unity3d.player.VideoPlayer" android:label="@string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:screenOrientation="reverseLandscape"> </activity> </application> <uses-feature android:glEsVersion="0x00020000" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" android:required="true" /> <uses-feature android:name="android.hardware.camera.front" android:required="true" /> <uses-sdk android:minSdkVersion="6" android:targetSdkVersion="15" /> </manifest>
Have you tried using default values for width, height and refresh rate? Maybe the settings you're requesting aren't possible with the device.
Unfortunately, I don't know how to query the phone to figure out what the default values are - specs on the phone are 1080p on the main camera, 720p on the front-facing one - I've tried those and every other standard resolution I can think of, but none of them make any difference In any case, according to the script reference, all I'm specifying are the requested width, height, fps: "The real width [height, frame rate] may be different, and will match the closest width [height, frame rate] supported by the device." So shouldn't it work whatever resolution I'm requesting? Meanwhile, does anyone have any suggestions regarding the AndroidManifest file? Does anything look wrong? I'd really love to get this working.
Well what I meant was not specifying a width/height/refresh rate. You can call the constructor without those things. Have you tried just doing a really stripped down test version? I can get the camera to work absolutely fine with: Start: Code (csharp): m_CameraTexture = new WebCamTexture(WebCamTexture.devices[0].name); if (m_CameraTexture != null) { m_CameraTexture.Play(); } Update: Code (csharp): if (m_CameraTexture != null m_CameraTexture.didUpdateThisFrame) { transform.renderer.material.mainTexture = m_CameraTexture; }
Didn't realize I could call constructor without those parameters, thanks. Tried it. Still nothing. Just like the more complicated version: when I run your stripped down version on the desktop or iPhone, it works fine. On Android (Samsung Galaxy Nexus), just a black plane.
I don't have anything productive to offer, other than a "me too" - on an Asus Eee Transformer TF-101 (last year's version), it reports two cameras and everything looks fine except the picture is just black, whichever camera I use. I tried the same authorization request code that you're using, and confirmed via OnGUI that HasUserAuthorization is returning true. I have no idea where to find the manifest file, let alone what it ought to look like! As far as I can tell, Unity generates an APK and copies it straight to the device, and everything works except the camera. I found a lot of old threads, and UnityAnswers questions, on this topic but I think MADmarine's post is the first time I've seen anybody saying it actually works for them!
I guess I should count myself lucky then... If it helps I'm running Android 3.1 on a Toshiba AT100 Tablet. Have you checked if there are any Android updates to your devices?
George - The Android Manifest file is created when you build your application for Android - there's a Temp folder in the project folder, inside that a StagingArea folder gets created when you build, and inside that is the AndroidManifest.xml file. The manifest gets created on the fly every time you build your app, but as I understand it, you can move it to Assets/Plugins/Android/, make any changes you want to it, and then that's the manifest that will be loaded next time you build. Someone with more knowledge than me should confirm that I've got all the facts right on this. And (speaking of people with more knowledge than me) I would really appreciate it if someone - anyone - who understands these things could take a look at the Android Manifest file that I posted above and make some suggestions about what alterations or updates might have an effect. MADmarine - phones are up to date, don't think that's the problem tonydongyiqi? wccrawford? Anyone? Care to help us out here?
Someone just PM'ed me with a few more questions about how I got the camera to work on my tablet, I thought I'd just share some of my answers just in case it helps anyone else: I think it may be written somewhere that Android 4.0.3 is needed for the camera, but it is definitely not required for it to run on the tablet/phone. I do think you have to have the 4.0.3 SDK installed on your development system however. I'm not sure what the key bit of info is to getting the camera to work, so I'll just list as many things as I can about what I'm doing and hopefully you'll manage to get it working. I made sure that I downloaded the latest SDK for Android along with some others and pointed Unity at that. So have on my system the SDKs for 4.0.3, 2.3.3, and 2.1 installed. And that's WITH the Google APIs for each. In my Unity settings I put the minimum API Level as 2.3.3 Gingerbread (API level 10). The other settings are mostly at default (ARMv7 only, OpenGL ES 2.0, with auto install and internet access, write access to external storage). I don't know if this also makes a massive difference, but I don't start up my camera straight away. I find that if I try to do too much with the camera in a single frame my tablet crashes too. So perhaps try having a button in your app that will start up the camera (just for testing this out anyway), don't try to start up at the same time as the app.
I've got all the Android SDKs installed, and the Google APIs as well. As far as "pointing Unity towards the SDK" - you just mean the setting in Preferences/External Tools/Android SDK Location, right? I have that set to /Developer/android-sdk-macosx I tried changing the minimum API level at 2.3.3 (and tried 4.0 also, since that's what's running on the phone). I tried using a button to start the camera up, instead of starting it up with the app. Still getting nothing but a big black rectangle. Anyway, MADmarine, I really appreciate all your help on this, whether we've solved it or not. Obviously I'm not the only one having this problem, but in the absence of anyone else chiming in with any ideas or suggestions (by now I would have expected somebody from Unity to offer some kind of support) I guess I will have to conclude that this is a bug, and that I should just file a bug report and give up until it gets fixed. Code (csharp): #pragma strict private var m_CameraTexture : WebCamTexture; function Start () { } function Update () { if (m_CameraTexture != null m_CameraTexture.didUpdateThisFrame) { transform.renderer.material.mainTexture = m_CameraTexture; } } function OnGUI() { if (GUI.Button(Rect(50,10,200,50),"Start WebCam")) { m_CameraTexture = new WebCamTexture(WebCamTexture.devices[0].name); if (m_CameraTexture != null) { m_CameraTexture.Play(); } } }
Yep, sorry I wasn't too clear about that SDK part. It definitely shouldn't be this hard to get the camera working so there's a bug or two somewhere I agree. I guess another thing different from my setup is that I'm using C#, but this is just clutching at straws now. Hope you get it fixed soon.
Hi MADmarine, thanks for giving more details. I wondered whether you could upload a working .apk file so we can test it on our devices? It would determine once and for all whether it's a device problem or a build problem. Thanks
I get the same black texture on my droid-X. Perhaps could you share your working android manifest? With DDMS I do see some errors. Code (csharp): 04-06 00:56:45.116: D/CameraSettings(1223): defaultCapabilities: preview-size-values: 176x144,320x240,352x288,640x480,720x480,800x448,1280x720 04-06 00:56:45.116: D/CameraSettings(1223): defaultCapabilities: preview-frame-rate-values: 5,10,15,20,24,25,28,30 04-06 00:56:45.123: D/CameraSettings(1223): defaultCapabilities: picture-format-values: jpeg,jfif,exif 04-06 00:56:45.123: D/CameraSettings(1223): defaultCapabilities: picture-size-values: 640x480,1280x960,1600x1200,2048x1536,2592x1936,3264x1840,3264x2448 04-06 00:56:45.123: D/CameraSettings(1223): defaultCapabilities: jpeg-thumbnail-size-values: 0x0,160x90,160x120,176x144,320x180,320x240 04-06 00:56:06.373: E/OMXCodec(1223): Successfully allocated software codec 'VorbisDecoder' 04-06 00:55:31.645: E/CameraSettings(1223): Param type 50 not supported 04-06 00:56:06.389: W/CameraHal(1223): No overlay set before start preview I'll try the thumbnail size to see if I get an image... It sucks that the API doesn't give access to the capabilities. Unless it does and I haven't seen that doc yet...
This script works on my macbook pro, and on a toshiba thrive. No luck on droid-x. On the thrive, both cameras are detected. Code (csharp): using System; using UnityEngine; using System.Collections.Generic; public class CameraTest : MonoBehaviour { /// <summary> /// Meta reference to the camera /// </summary> public Material CameraMaterial = null; /// <summary> /// The number of frames per second /// </summary> private int m_framesPerSecond = 0; /// <summary> /// The current frame count /// </summary> private int m_frameCount = 0; /// <summary> /// The frames timer /// </summary> private DateTime m_timerFrames = DateTime.MinValue; /// <summary> /// The selected device index /// </summary> private int m_indexDevice = -1; /// <summary> /// The web cam texture /// </summary> private WebCamTexture m_texture = null; // Use this for initialization void Start() { if (null == CameraMaterial) { throw new ApplicationException("Missing camera material reference"); } Application.RequestUserAuthorization(UserAuthorization.WebCam); } void OnGUI() { if (m_timerFrames < DateTime.Now) { m_framesPerSecond = m_frameCount; m_frameCount = 0; m_timerFrames = DateTime.Now + TimeSpan.FromSeconds(1); } ++m_frameCount; GUILayout.Label(string.Format("Frames per second: {0}", m_framesPerSecond)); if (m_indexDevice >= 0 WebCamTexture.devices.Length > 0) { GUILayout.Label(string.Format("Selected Device: {0}", WebCamTexture.devices[m_indexDevice].name)); } if (Application.HasUserAuthorization(UserAuthorization.WebCam)) { GUILayout.Label("Has WebCam Authorization"); if (null == WebCamTexture.devices) { GUILayout.Label("Null web cam devices"); } else { GUILayout.Label(string.Format("{0} web cam devices", WebCamTexture.devices.Length)); for (int index = 0; index < WebCamTexture.devices.Length; ++index) { var device = WebCamTexture.devices[index]; if (string.IsNullOrEmpty(device.name)) { GUILayout.Label("unnamed web cam device"); continue; } if (GUILayout.Button(string.Format("web cam device {0}{1}{2}", m_indexDevice == index ? "[" : string.Empty, device.name, m_indexDevice == index ? "]" : string.Empty), GUILayout.MinWidth(200), GUILayout.MinHeight(50))) { m_indexDevice = index; // stop playing if (null != m_texture) { if (m_texture.isPlaying) { m_texture.Stop(); } } // destroy the old texture if (null != m_texture) { UnityEngine.Object.DestroyImmediate(m_texture, true); } // use the device name m_texture = new WebCamTexture(device.name); // start playing m_texture.Play(); // assign the texture CameraMaterial.mainTexture = m_texture; } } } } else { GUILayout.Label("Pending WebCam Authorization..."); } } // Update is called once per frame private void Update() { if (null != m_texture m_texture.didUpdateThisFrame) { CameraMaterial.mainTexture = m_texture; } } }
I get the same issues as tgraupmann, and can't seem to find a solution either, other than looking elsewhere. Prime31s plugin works, but it launches an entirely seperate activity which isn't what we want. checking out the logcat, get interesting dump of camera stats, but nothing that hints at what maybe amiss, except the mysterious param 50, 51, and 53. Condensed log output: 04-13 16:03:19.453: I/Unity(2365): Webcam permission = True 04-13 16:03:19.476: I/Unity(2365): Webcame devices = 1 04-13 16:03:19.508: I/Unity(2365): Cam back-facing device[0] = Camera 0 04-13 16:03:19.508: D/Unity(2365): Create: m_DeviceName='Camera 0', device=0, w=0, h=0, fps=0 04-13 16:03:19.508: I/Unity(2365): getNumCameras: 1 04-13 16:03:19.508: I/Unity(2365): initCamera: 0 04-13 16:03:19.812: D/CameraCompModule(1208): Focus distance (0) = 3.151, Infinity, Infinity 04-13 16:03:19.828: D/Unity(2365): sz = 176x144 04-13 16:03:19.828: D/Unity(2365): sz = 320x240 04-13 16:03:19.828: D/Unity(2365): sz = 352x288 04-13 16:03:19.828: D/Unity(2365): sz = 640x480 04-13 16:03:19.828: D/Unity(2365): sz = 720x480 04-13 16:03:19.828: D/Unity(2365): sz = 800x448 04-13 16:03:19.828: D/Unity(2365): sz = 1280x720 04-13 16:03:19.844: D/CameraSettings(1208): Extract changes completed, 0 total changes 04-13 16:03:19.844: D/Unity(2365): cam[0]: size = 640x480; format=17, fps=(15000, 30000), bpp=12 04-13 16:03:19.844: D/CameraCompModule(1208): Focus distance (0) = 3.151, Infinity, Infinity 04-13 16:03:19.844: E/CameraSettings(1208): Param type 50 not supported 04-13 16:03:19.844: D/CameraHal(1208): focus-distance = 3.151, Infinity, Infinity 04-13 16:03:19.844: W/CameraHal(1208): No overlay set before start preview
Upgraded Unity to 3.5.1f2 - just checked both my Android phones, no change, the problem persists. I have to say, the situation is really frustrating - this is some pretty basic essential missing functionality, and we're going on two months with no solution in sight and no response at all from our friends at Unity.
I am having this problem with a galaxy W, the galaxy s 2 i tried is not having such an issue. scanning the logcat i found that there are a couple of lines which seem important: 04-17 15:06:39.142: E/CAM_FD(1395): cam_conf open driver failed: Device or resource busy! 04-17 15:06:39.142: E/CAM_FD(1395): cam_conf: CAMERA_EXIT So my question is this - is Unity3.5 somehow setting the camera to busy by default? I have altered the manifest to show either Camera permissions or not, and it has no effect.
Same thing with my galaxy nexus, I have a black texture. I tried also to use Qualcomm AR demos that uses cameras, I don't know if they use the webcameratexture but still not working. Everything is going well on my iPad. I hope they'll fix it very soon.
Also having the black texture problem on the HTC One X running Android 4.0.3. Has anyone heard anything official about this from Unity support?
Nope. Filed bug report but no response yet. Got my hands on a HTC Rezound - works fine. So here's the current score: WebCamTexture works on these phones Samsung Nexus S (v2.3.4) Sony Ericsson Xperia Play (v2.3.4) Sony Ericsson Xperia Mini (v2.3.4) Toshiba AT100 (v3.1) HTC Rezound (v2.3.4) Toshiba AT100 / Thrive (v3.1) Samsung Galaxy S2 WebCamTexture doesn't work on these phones Samsung Galaxy Nexus (v 4.0.1) Samsung Galaxy W LG Optimus Thrill 4G (v2.3) Asus Eee Transformer TF-101 Motorola Droid-x HTC One X (v4.0.3)
Noticed this in the change log for 3.5.2: "Android: Fixed Webcam texture initialization problem on ICS device." Has this fixed the issue for anyone?
Interesting. I'll got my new testdevice in the beginning of the next week. Maybe someone else could test it with 3.5.2 and post it
Today I got my Nexus S on 4.0.4 - the same error. Still black. That's more as bad, because my next App needs the Camera feature -.- Does anyone know if the Pime31-Cam-Plugins works?
I just checked to see if Unity 3.5.2 had fixed this problem on my HTC One X (android 4.04) and it is still displaying a black texture.
Just letting everyone know that i'm still not getting anything on the HTC One X. However, I have had some success on the HTC Desire S and the webcamTexture can be used as both a GUITexture or Object texture. Here is the code for for GUITexture Code (csharp): using UnityEngine; using System.Collections; [RequireComponent(typeof(GUITexture))] public class WebcamTexturePlain : MonoBehaviour { // Texture to apply to the GUITexture we're attached to private WebCamTexture webcamTexture; // Use this for initialization void Start () { // Initialise and apply texture webcamTexture = new WebCamTexture(WebCamTexture.devices[0].name); // Apply the texture GUITexture guiTexture = this.GetComponent(typeof(GUITexture)) as GUITexture; guiTexture.texture = webcamTexture; // Puts GUITexture in the center of the screen. guiTexture.transform.position = new Vector3(0.5f,0.5f,0.5f); } // Update is called once per frame void Update () { // Start the webcam texture if it's frozen if (!webcamTexture.isPlaying) { webcamTexture.Play(); } } } Code for Object Texture Code (csharp): using UnityEngine; using System.Collections; public class WebCamera : MonoBehaviour { private WebCamDevice[] devices; private WebCamTexture webCam; // Use this for initialization void Start () { devices = WebCamTexture.devices; webCam = new WebCamTexture(WebCamTexture.devices[0].name); // Starts the webcam. webCam.Play (); // Applies texture to object. transform.renderer.material.mainTexture = webCam; } } I'll also be testing to see if the fault is also on the ASUS Transformer Pad 300 later tonight and I'll report back. UPDATE ASUS Transformer Pad 300 also displays the black screen.
I met same issue on Galaxy Nexus and SHARP AQUOS PHONE 102SH yet, using Unity 3.5.2. No fixing issue, I cannot say that Android supported. I hope that hurry to fix this issues. but i have no ideas. Append comment : Seems Samsung Galaxy S3 also cannot work. My app decrease user rating stars on Google play, since this issues. I update score: WebCamTexture works on these phones Samsung Nexus S (v2.3.4) Samsung Galaxy S2 Sony Ericsson Xperia Play (v2.3.4) Sony Ericsson Xperia Mini (v2.3.4) Toshiba AT100 (v3.1) Toshiba AT100 / Thrive (v3.1) HTC Rezound (v2.3.4) HTC Desire S NEC MEDIAS N-04C(v2.3.3) NEC MEDIAS N-04D(v2.3.3) WebCamTexture doesn't work on these phones Samsung Galaxy Nexus (v 4.0.1) Samsung Galaxy S3 Samsung Galaxy W LG Optimus Thrill 4G (v2.3) Asus Eee Transformer TF-101 Motorola Droid-x HTC One X (v4.0.3) SHARP AQUOS PHONE 102SH Nexus S (v4.0.4)
Adding information: Webcam texture worked with somewhat low frame rates in a Samsung GP-1000L (android 2.3.3), and perfectly smooth in a Samsung Galaxy S YP-G70 (android 2.3.5).
Anybody found a solution to the webcam texture issue on Android? I'm thinking about using Vuforia and accessing the camera image from there as it seems to work well on all the phones I've tested on. Has anyone done this?
Cool idea and it's free But I've never test it. Is it hard to capture the camera-image trough Vuforia? Any code-sample? Are you sure that this works well via Unity on Android-devices?
I have tested using Vuforia. Worked alright for both iPhone and Android (galaxy s). There is a simple trick that allow you to use vuforia camera as a texture explained in their manual. Drawback is that texture has a black area to keep its size quadratic, and even with UV mapping I failed to get rid of it. I did not find a way to change camera resolution, too.
Is there any way to import photos from gallery to texture folder(means accessing gallery photos from app) and use the same image as a texture in unity 3d????