{"id":262715,"date":"2024-10-18T20:07:45","date_gmt":"2024-10-18T20:07:45","guid":{"rendered":"https:\/\/michigandigitalnews.com\/index.php\/2024\/10\/18\/camerax-update-makes-dual-concurrent-camera-even-easier\/"},"modified":"2025-06-25T17:10:47","modified_gmt":"2025-06-25T17:10:47","slug":"camerax-update-makes-dual-concurrent-camera-even-easier","status":"publish","type":"post","link":"https:\/\/michigandigitalnews.com\/index.php\/2024\/10\/18\/camerax-update-makes-dual-concurrent-camera-even-easier\/","title":{"rendered":"CameraX update makes dual concurrent camera even easier"},"content":{"rendered":"<p> [ad_1]<br \/>\n<\/p>\n<div>\n<meta name=\"twitter:image\" content=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEj23eacL7I9W71-SdbqFZ7LXwVcaeJN3EROAUN8XBwF7_ZF8tw1cql0xxjc3iBOsudo3Rp2i1cMLmXUXD_5Cq44hcOA5LRshWvrs9WY92dXtIbH9WpiEs_VSrgGcs7F6ZSTlhHCQ-5C36KSkRC0nzcsg8rVzGNwpNlMzCRmo198wz9SVowNA1MRlNFKWbU\/s1600\/AndroidSpotlight_Adaptive_CameraX_Metadata_01.png\"\/><br \/>\n<img decoding=\"async\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEj23eacL7I9W71-SdbqFZ7LXwVcaeJN3EROAUN8XBwF7_ZF8tw1cql0xxjc3iBOsudo3Rp2i1cMLmXUXD_5Cq44hcOA5LRshWvrs9WY92dXtIbH9WpiEs_VSrgGcs7F6ZSTlhHCQ-5C36KSkRC0nzcsg8rVzGNwpNlMzCRmo198wz9SVowNA1MRlNFKWbU\/s1600\/AndroidSpotlight_Adaptive_CameraX_Metadata_01.png\" style=\"display:none\"\/><\/p>\n<p><em>Posted by Donovan McMurray \u2013 Developer Relations Engineer<\/em><\/p>\n<p><a href=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhwVBYvbASuJqx4wj4F6d6lIGlmENzJQPII78U__fio6gGLoup4vZA7RcGh40VZrszXXaFZYv8oLBX0GcSBwIJi6Mk-wFeocM4sjG0-nUAgNLwdR9fFVSDQluveqXESCqCr0QqxPhth0gZCSMwCvjUG4kMdhmpOiIY66uXNFnQvdB3otfn89i9IU_2Ip9I\/s1600\/AndroidSpotlight_Adaptive_CameraX_Banner_01.png\" imageanchor=\"1\"><img decoding=\"async\" border=\"0\" data-original-height=\"800\" data-original-width=\"100%\" src=\"https:\/\/blogger.googleusercontent.com\/img\/b\/R29vZ2xl\/AVvXsEhwVBYvbASuJqx4wj4F6d6lIGlmENzJQPII78U__fio6gGLoup4vZA7RcGh40VZrszXXaFZYv8oLBX0GcSBwIJi6Mk-wFeocM4sjG0-nUAgNLwdR9fFVSDQluveqXESCqCr0QqxPhth0gZCSMwCvjUG4kMdhmpOiIY66uXNFnQvdB3otfn89i9IU_2Ip9I\/s1600\/AndroidSpotlight_Adaptive_CameraX_Banner_01.png\" style=\"100%\"\/><\/a><\/p>\n<p><a href=\"https:\/\/developer.android.com\/media\/camera\/camerax\" target=\"_blank\" rel=\"noopener\">CameraX<\/a>, Android&#8217;s Jetpack camera library, is getting an exciting update to its Dual Concurrent Camera feature, making it even easier to integrate this feature into your app. This feature allows you to stream from 2 different cameras at the same time. The original version of Dual Concurrent Camera was <a href=\"https:\/\/android-developers.googleblog.com\/2023\/06\/camerax-13-is-now-in-beta.html\" target=\"_blank\" rel=\"noopener\">released in CameraX 1.3.0<\/a>, and it was already a huge leap in making this feature easier to implement.<\/p>\n<p>Starting with <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/camera#1.5.0-alpha01\" target=\"_blank\" rel=\"noopener\">1.5.0-alpha01<\/a>, CameraX will now handle the composition of the 2 camera streams as well. This update is additional functionality, and it doesn\u2019t remove any prior functionality nor is it a breaking change to your existing Dual Concurrent Camera code. To tell CameraX to handle the composition, simply use the <a href=\"https:\/\/developer.android.com\/reference\/androidx\/camera\/core\/ConcurrentCamera.SingleCameraConfig#SingleCameraConfig%28androidx.camera.core.CameraSelector,androidx.camera.core.UseCaseGroup,androidx.camera.core.CompositionSettings,androidx.lifecycle.LifecycleOwner%29\" target=\"_blank\" rel=\"noopener\">new <span style=\"font-family: Courier\">SingleCameraConfig<\/span> constructor<\/a> which has a new parameter for a <span style=\"font-family: Courier\"><a href=\"https:\/\/developer.android.com\/reference\/androidx\/camera\/core\/CompositionSettings\" target=\"_blank\" rel=\"noopener\">CompositionSettings<\/a><\/span> object. Since you\u2019ll be creating 2 SingleCameraConfigs, you should be consistent with what constructor you use.<\/p>\n<p>Nothing has changed in the way you check for concurrent camera support from the prior version of this feature. As a reminder, here is what that code looks like.<\/p>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ Set up primary and secondary camera selectors if supported on device.<\/span>\n<span style=\"color: #008000; font-weight: bold\">var<\/span> primaryCameraSelector: CameraSelector? = <span style=\"color: #008000; font-weight: bold\">null<\/span>\n<span style=\"color: #008000; font-weight: bold\">var<\/span> secondaryCameraSelector: CameraSelector? = <span style=\"color: #008000; font-weight: bold\">null<\/span>\n\n<span style=\"color: #008000; font-weight: bold\">for<\/span> (cameraInfos <span style=\"color: #008000; font-weight: bold\">in<\/span> cameraProvider.availableConcurrentCameraInfos) {\n    primaryCameraSelector = cameraInfos.first {\n        it.lensFacing == CameraSelector.LENS_FACING_FRONT\n    }.cameraSelector\n    secondaryCameraSelector = cameraInfos.first {\n        it.lensFacing == CameraSelector.LENS_FACING_BACK\n    }.cameraSelector\n\n    <span style=\"color: #008000; font-weight: bold\">if<\/span> (primaryCameraSelector == <span style=\"color: #008000; font-weight: bold\">null<\/span> || secondaryCameraSelector == <span style=\"color: #008000; font-weight: bold\">null<\/span>) {\n        <span style=\"color: #408080; font-style: italic\">\/\/ If either a primary or secondary selector wasn't found, reset both<\/span>\n        <span style=\"color: #408080; font-style: italic\">\/\/ to move on to the next list of CameraInfos.<\/span>\n        primaryCameraSelector = <span style=\"color: #008000; font-weight: bold\">null<\/span>\n        secondaryCameraSelector = <span style=\"color: #008000; font-weight: bold\">null<\/span>\n    } <span style=\"color: #008000; font-weight: bold\">else<\/span> {\n        <span style=\"color: #408080; font-style: italic\">\/\/ If both primary and secondary camera selectors were found, we can<\/span>\n        <span style=\"color: #408080; font-style: italic\">\/\/ conclude the search.<\/span>\n        <span style=\"color: #008000; font-weight: bold\">break<\/span>\n    }\n}\n\n<span style=\"color: #008000; font-weight: bold\">if<\/span> (primaryCameraSelector == <span style=\"color: #008000; font-weight: bold\">null<\/span> || secondaryCameraSelector == <span style=\"color: #008000; font-weight: bold\">null<\/span>) {\n    <span style=\"color: #408080; font-style: italic\">\/\/ Front and back concurrent camera not available. Handle accordingly.<\/span>\n}\n<\/pre>\n<\/div>\n<p>Here\u2019s the updated code snippet showing how to implement picture-in-picture, with the front camera stream scaled down to fit into the lower right corner. In this example, CameraX handles the composition of the camera streams.<\/p>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ If 2 concurrent camera selectors were found, create 2 SingleCameraConfigs<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ and compose them in a picture-in-picture layout.<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> primary = SingleCameraConfig(\n    cameraSelectorPrimary,\n    useCaseGroup,\n    CompositionSettings.Builder()\n        .setAlpha(<span style=\"color: #666666\">1.0f<\/span>)\n        .setOffset(<span style=\"color: #666666\">0.0f<\/span>, <span style=\"color: #666666\">0.0f<\/span>)\n        .setScale(<span style=\"color: #666666\">1.0f<\/span>, <span style=\"color: #666666\">1.0f<\/span>)\n        .build(),\n    lifecycleOwner);\n<span style=\"color: #008000; font-weight: bold\">val<\/span> secondary = SingleCameraConfig(\n    cameraSelectorSecondary,\n    useCaseGroup,\n    CompositionSettings.Builder()\n        .setAlpha(<span style=\"color: #666666\">1.0f<\/span>)\n        .setOffset(<span style=\"color: #666666\">2<\/span> \/ <span style=\"color: #666666\">3f<\/span> - <span style=\"color: #666666\">0.1f<\/span>, -<span style=\"color: #666666\">2<\/span> \/ <span style=\"color: #666666\">3f<\/span> + <span style=\"color: #666666\">0.1f<\/span>)\n        .setScale(<span style=\"color: #666666\">1<\/span> \/ <span style=\"color: #666666\">3f<\/span>, <span style=\"color: #666666\">1<\/span> \/ <span style=\"color: #666666\">3f<\/span>)\n        .build()\n    lifecycleOwner);\n\n<span style=\"color: #408080; font-style: italic\">\/\/ Bind to lifecycle<\/span>\nConcurrentCamera concurrentCamera =\n    cameraProvider.bindToLifecycle(listOf(primary, secondary));\n<\/pre>\n<\/div>\n<p>You are not constrained to a picture-in-picture layout. For instance, you could define a side-by-side layout by setting the offsets and scaling factors accordingly. You want to keep both dimensions scaled by the same amount to avoid a stretched preview. Here\u2019s how that might look.<\/p>\n<div style=\"background: #f8f8f8; overflow:auto;width:auto;border:0;\">\n<pre style=\"margin: 0; line-height: 125%\"><span style=\"color: #408080; font-style: italic\">\/\/ If 2 concurrent camera selectors were found, create 2 SingleCameraConfigs<\/span>\n<span style=\"color: #408080; font-style: italic\">\/\/ and compose them in a picture-in-picture layout.<\/span>\n<span style=\"color: #008000; font-weight: bold\">val<\/span> primary = SingleCameraConfig(\n    cameraSelectorPrimary,\n    useCaseGroup,\n    CompositionSettings.Builder()\n        .setAlpha(<span style=\"color: #666666\">1.0f<\/span>)\n        .setOffset(<span style=\"color: #666666\">0.0f<\/span>, <span style=\"color: #666666\">0.25f<\/span>)\n        .setScale(<span style=\"color: #666666\">0.5f<\/span>, <span style=\"color: #666666\">0.5f<\/span>)\n        .build(),\n    lifecycleOwner);\n<span style=\"color: #008000; font-weight: bold\">val<\/span> secondary = SingleCameraConfig(\n    cameraSelectorSecondary,\n    useCaseGroup,\n    CompositionSettings.Builder()\n        .setAlpha(<span style=\"color: #666666\">1.0f<\/span>)\n        .setOffset(<span style=\"color: #666666\">0.5f<\/span>, <span style=\"color: #666666\">0.25f<\/span>)\n        .setScale(<span style=\"color: #666666\">0.5f<\/span>, <span style=\"color: #666666\">0.5f<\/span>)\n        .build()\n    lifecycleOwner);\n\n<span style=\"color: #408080; font-style: italic\">\/\/ Bind to lifecycle<\/span>\nConcurrentCamera concurrentCamera =\n    cameraProvider.bindToLifecycle(listOf(primary, secondary));\n<\/pre>\n<\/div>\n<p>We\u2019re excited to offer this improvement to an already developer-friendly feature. Truly the CameraX way! <span style=\"color: #0D904F; font-family: Courier\">CompositionSettings<\/span> in Dual Concurrent Camera is currently in alpha, so if you have feature requests to improve upon it before the API is locked in, please give us feedback in the <a href=\"https:\/\/groups.google.com\/a\/android.com\/g\/camerax-developers\" target=\"_blank\" rel=\"noopener\">CameraX Discussion Group<\/a>. And check out the <a href=\"https:\/\/developer.android.com\/jetpack\/androidx\/releases\/camera#1.5.0-alpha01\" target=\"_blank\" rel=\"noopener\">full CameraX 1.5.0-alpha01<\/a> release notes to see what else is new in CameraX.<\/p>\n<\/div>\n<p>[ad_2]<br \/>\n<br \/><a href=\"http:\/\/android-developers.googleblog.com\/2024\/10\/camerax-update-makes-dual-concurrent-camera-easier.html\">Source link <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>[ad_1] Posted by Donovan McMurray \u2013 Developer Relations Engineer CameraX, Android&#8217;s Jetpack camera library, is getting an exciting update to its Dual Concurrent Camera feature,<\/p>\n","protected":false},"author":1,"featured_media":262716,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[146],"tags":[],"_links":{"self":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/262715"}],"collection":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/comments?post=262715"}],"version-history":[{"count":0,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/posts\/262715\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media\/262716"}],"wp:attachment":[{"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/media?parent=262715"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/categories?post=262715"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/michigandigitalnews.com\/index.php\/wp-json\/wp\/v2\/tags?post=262715"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}