Skip to content

Commit

Permalink
fix(core): fix when the device doesn't have a camera with name '0'.
Browse files Browse the repository at this point in the history
  • Loading branch information
ThibaultBee committed Oct 15, 2023
1 parent 0798b49 commit 6d70915
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import io.github.thibaultbee.streampack.data.VideoConfig
import io.github.thibaultbee.streampack.internal.data.Frame
import io.github.thibaultbee.streampack.internal.sources.IVideoCapture
import io.github.thibaultbee.streampack.utils.CameraSettings
import io.github.thibaultbee.streampack.utils.defaultCameraId
import io.github.thibaultbee.streampack.utils.isFrameRateSupported
import kotlinx.coroutines.runBlocking
import java.nio.ByteBuffer
Expand All @@ -32,7 +33,7 @@ class CameraCapture(
) : IVideoCapture {
var previewSurface: Surface? = null
override var encoderSurface: Surface? = null
var cameraId: String = "0"
var cameraId: String = context.defaultCameraId
get() = cameraController.cameraId ?: field
@RequiresPermission(Manifest.permission.CAMERA)
set(value) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@ import android.graphics.ImageFormat
import android.hardware.camera2.CameraCharacteristics
import android.util.Range
import android.util.Size
import io.github.thibaultbee.streampack.utils.cameraList
import io.github.thibaultbee.streampack.utils.getCameraCharacteristics
import io.github.thibaultbee.streampack.utils.getCameraList

/**
* Gets all output capture sizes.
*
* @return List of resolutions supported by all camera
*/
fun Context.getCameraOutputStreamSizes(): List<Size> {
val cameraIdList = this.getCameraList()
val cameraIdList = cameraList
val resolutionSet = mutableSetOf<Size>()
cameraIdList.forEach { cameraId ->
resolutionSet.addAll(getCameraOutputStreamSizes(cameraId))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ import io.github.thibaultbee.streampack.listeners.OnErrorListener
import io.github.thibaultbee.streampack.streamers.helpers.CameraStreamerConfigurationHelper
import io.github.thibaultbee.streampack.streamers.interfaces.ICameraStreamer
import io.github.thibaultbee.streampack.streamers.settings.BaseCameraStreamerSettings
import io.github.thibaultbee.streampack.utils.getCameraList
import io.github.thibaultbee.streampack.views.AutoFitSurfaceView
import io.github.thibaultbee.streampack.views.PreviewView
import kotlinx.coroutines.runBlocking

/**
Expand Down Expand Up @@ -76,7 +74,7 @@ open class BaseCameraStreamer(
/**
* Set current camera id.
*
* @param value string that described the camera. Retrieves list of camera from [Context.getCameraList]
* @param value string that described the camera. Retrieves list of camera from [Context.cameraList]
*/
@RequiresPermission(Manifest.permission.CAMERA)
set(value) {
Expand All @@ -93,7 +91,7 @@ open class BaseCameraStreamer(
* Inside, it launches both camera and microphone capture.
*
* @param previewSurface Where to display camera capture. Could be a [Surface] from a [StreamerSurfaceView], an [AutoFitSurfaceView], a [SurfaceView] or a [TextureView].
* @param cameraId camera id (get camera id list from [Context.getCameraList])
* @param cameraId camera id (get camera id list from [Context.cameraList])
*
* @throws [StreamPackError] if audio or video capture couldn't be launch
* @see [stopPreview]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,43 +35,68 @@ fun Context.getCameraCharacteristics(cameraId: String): CameraCharacteristics {
return cameraManager.getCameraCharacteristics(cameraId)
}

/**
* Get default camera id.
*
* If a back camera is available, returns the first back camera id.
* If no back camera is available, returns the first camera id.
*
* @return default camera id
*/
val Context.defaultCameraId: String
get() {
val cameraList = this.cameraList
if (cameraList.isEmpty()) {
throw IllegalStateException("No camera available")
}
val backCameraList = this.backCameraList
return if (backCameraList.isEmpty()) {
cameraList.first()
} else {
backCameraList.first()
}
}

/**
* Gets camera id list.
*
* @return List of camera ids
*/
fun Context.getCameraList(): List<String> {
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
return cameraManager.cameraIdList.toList()
}
val Context.cameraList: List<String>
get() {
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
return cameraManager.cameraIdList.toList()
}


/**
* Gets back camera id list.
*
* @return List of back camera ids
*/
fun Context.getBackCameraList() =
getCameraList().filter { getFacingDirection(it) == CameraCharacteristics.LENS_FACING_BACK }
val Context.backCameraList: List<String>
get() = cameraList.filter { getFacingDirection(it) == CameraCharacteristics.LENS_FACING_BACK }

/**
* Gets back camera id list.
* Gets front camera id list.
*
* @return List of front camera ids
*/
fun Context.getFrontCameraList() =
getCameraList().filter { getFacingDirection(it) == CameraCharacteristics.LENS_FACING_FRONT }
val Context.frontCameraList: List<String>
get() = cameraList.filter { getFacingDirection(it) == CameraCharacteristics.LENS_FACING_FRONT }

/**
* Gets external camera id list.
*
* @return List of front camera ids
*/
fun Context.getExternalCameraList() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
getCameraList().filter { getFacingDirection(it) == CameraCharacteristics.LENS_FACING_EXTERNAL }
} else {
emptyList()
}
val Context.externalCameraList: List<String>
get() =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
cameraList.filter { getFacingDirection(it) == CameraCharacteristics.LENS_FACING_EXTERNAL }
} else {
emptyList()
}

/**
* Check if string is a back camera id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ import androidx.core.app.ActivityCompat
import io.github.thibaultbee.streampack.R
import io.github.thibaultbee.streampack.logger.Logger
import io.github.thibaultbee.streampack.streamers.interfaces.ICameraStreamer
import io.github.thibaultbee.streampack.utils.*
import io.github.thibaultbee.streampack.utils.OrientationUtils
import io.github.thibaultbee.streampack.utils.TAG
import io.github.thibaultbee.streampack.utils.backCameraList
import io.github.thibaultbee.streampack.utils.frontCameraList
import io.github.thibaultbee.streampack.utils.getCameraCharacteristics

/**
* A [FrameLayout] containing a [AutoFitSurfaceView] that manages [ICameraStreamer] preview.
Expand Down Expand Up @@ -86,10 +90,11 @@ class PreviewView @JvmOverloads constructor(
)
defaultCameraId = when (cameraFacingDirection) {
FacingDirection.FRONT -> {
context.getFrontCameraList().firstOrNull()
context.frontCameraList.firstOrNull()
}

FacingDirection.BACK -> {
context.getBackCameraList().firstOrNull()
context.backCameraList.firstOrNull()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ import android.media.MediaFormat
import android.os.Bundle
import android.text.InputFilter
import android.text.InputType
import androidx.preference.*
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.PreferenceCategory
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SeekBarPreference
import androidx.preference.SwitchPreference
import io.github.thibaultbee.streampack.app.R
import io.github.thibaultbee.streampack.app.models.EndpointFactory
import io.github.thibaultbee.streampack.app.models.EndpointType
Expand All @@ -32,7 +37,8 @@ import io.github.thibaultbee.streampack.app.utils.StreamerHelperFactory
import io.github.thibaultbee.streampack.data.VideoConfig
import io.github.thibaultbee.streampack.internal.encoders.MediaCodecHelper
import io.github.thibaultbee.streampack.streamers.helpers.CameraStreamerConfigurationHelper
import io.github.thibaultbee.streampack.utils.getCameraList
import io.github.thibaultbee.streampack.utils.cameraList
import io.github.thibaultbee.streampack.utils.defaultCameraId
import io.github.thibaultbee.streampack.utils.isFrameRateSupported
import java.io.IOException

Expand Down Expand Up @@ -201,7 +207,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
val supportedFramerates = streamerHelper.video.getSupportedFramerates(
requireContext(),
encoder,
"0"
requireContext().defaultCameraId
)
videoFpsListPreference.entryValues.filter { fps ->
supportedFramerates.any { it.contains(fps.toString().toInt()) }
Expand All @@ -211,7 +217,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
}
videoFpsListPreference.setOnPreferenceChangeListener { _, newValue ->
val fps = (newValue as String).toInt()
val unsupportedCameras = requireContext().getCameraList().filter {
val unsupportedCameras = requireContext().cameraList.filter {
!requireContext().isFrameRateSupported(it, fps)
}
if (unsupportedCameras.isNotEmpty()) {
Expand Down Expand Up @@ -381,7 +387,7 @@ class SettingsFragment : PreferenceFragmentCompat() {
if (audioProfileListPreference.entry == null) {
audioProfileListPreference.value =
if (profiles.contains(MediaCodecInfo.CodecProfileLevel.AACObjectLC)) {
MediaCodecInfo.CodecProfileLevel.AACObjectLC.toString()
MediaCodecInfo.CodecProfileLevel.AACObjectLC.toString()
} else if (profiles.isNotEmpty()) {
profiles.first().toString()
} else {
Expand Down Expand Up @@ -472,12 +478,15 @@ class SettingsFragment : PreferenceFragmentCompat() {
endpoint.hasFLVCapabilities -> {
FileExtension.FLV.extension
}

endpoint.hasTSCapabilities -> {
FileExtension.TS.extension
}

endpoint.hasMP4Capabilities -> {
FileExtension.MP4.extension
}

else -> {
throw IOException("Unknown file type")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class StreamerManager(
private val context: Context,
private val configuration: Configuration
) {
var streamer: IStreamer? = null
private var streamer: IStreamer? = null

var onErrorListener: OnErrorListener?
get() = streamer?.onErrorListener
Expand Down Expand Up @@ -134,9 +134,9 @@ class StreamerManager(
streamer?.getCameraStreamer()?.let {
// Handle devices with only one camera
val cameras = if (context.isBackCamera(it.camera)) {
context.getFrontCameraList()
context.frontCameraList
} else {
context.getBackCameraList()
context.backCameraList
}
if (cameras.isNotEmpty()) {
it.camera = cameras[0]
Expand Down

0 comments on commit 6d70915

Please sign in to comment.