অ্যান্ড্রয়েডের জন্য ক্যামেরা ডিভাইস গাইড

ক্যামেরা ডিভাইসের ধরণটি দুটি বৈশিষ্ট্য ব্যবহার করে বাস্তবায়িত হয়: PushAvStreamTransport , যা পুশ-ভিত্তিক প্রোটোকল ব্যবহার করে অডিও এবং ভিডিও স্ট্রিম পরিবহন পরিচালনা করে এবং WebRtcLiveView , যা লাইভস্ট্রিম এবং টকব্যাক নিয়ন্ত্রণ করার ক্ষমতা প্রদান করে।

কোনও বৈশিষ্ট্য ব্যবহার করার আগে বা বৈশিষ্ট্য আপডেট করার চেষ্টা করার আগে সর্বদা ডিভাইসের জন্য বৈশিষ্ট্য এবং কমান্ড সমর্থন পরীক্ষা করুন। নিয়ন্ত্রণ ডিভাইসগুলি দেখুনAndroid আরও তথ্যের জন্য.

হোম এপিআই ডিভাইসের ধরণ বৈশিষ্ট্য কোটলিন নমুনা অ্যাপ ব্যবহারের ধরণ

ক্যামেরা

Google Camera Device

home.matter.6006.types.0158

এমন একটি ডিভাইস যা স্থির ছবি বা ভিডিও ধারণ করে। ক্যামেরাগুলিতে অ্যাক্সেসযোগ্য লাইভস্ট্রিম, দ্বি-মুখী টকব্যাক, অথবা সনাক্তকরণ ইভেন্ট থাকতে পারে।

প্রয়োজনীয় বৈশিষ্ট্য
গুগল পুশএভিস্ট্রিমট্রান্সপোর্ট
গুগল ওয়েবআরটিসিলাইভভিউ

ক্যামেরা

একটি লাইভস্ট্রিম শুরু করুন

লাইভস্ট্রিম শুরু করতে, WebRtcLiveView বৈশিষ্ট্যের startLiveView() পদ্ধতিতে Session Description Protocol (SDP) স্ট্রিং পাঠান, যা তিনটি মান সম্বলিত WebRtcLiveViewTrait.StartLiveViewCommand.Response প্রদান করে:

  • অধিবেশনের জন্য এসডিপি।
  • সেশনের সময়কাল সেকেন্ডে।
  • সেশন আইডি, যা সেশন প্রসারিত বা সমাপ্ত করতে ব্যবহার করা যেতে পারে।
suspend fun getWebRtcLiveViewTrait(cameraDevice: HomeDevice) {
 return cameraDevice.type(GoogleCameraDevice).trait(WebRtcLiveView).first {
    it?.metadata?.sourceConnectivity?.connectivityState == ConnectivityState.ONLINE
  }

}

// Start the live view
suspend fun startCameraStream(trait: WebRtcLiveView, offerSdp: String) {
  val response = trait.startLiveView(offerSdp)
  // Response contains three fields (see below)
  return response
}
  ...

// This is used to manage the WebRTC connection
val peerConnection: RTCPeerConnection = ...

   ...

val startResponse = startCameraStream(sdp)
val answerSdp = startResponse?.answerSdp
val sessionDuration = startResponse?.liveSessionDurationSeconds
val mediaSessionId = startResponse?.mediaSessionId

peerConnection.setRemoteDescription(SessionDescription.Type.ANSWER,
                                    answerSdp)

লাইভস্ট্রিম প্রসারিত করুন

লাইভস্ট্রিমের একটি পূর্বনির্ধারিত সময়কাল থাকে যার পরে এর মেয়াদ শেষ হয়ে যায়। একটি সক্রিয় স্ট্রিমের সময়কাল বাড়ানোর জন্য, WebRtcLiveView.extendLiveView() পদ্ধতি ব্যবহার করে একটি এক্সটেনশন অনুরোধ জারি করুন:

// Assuming camera stream has just been started
suspend fun scheduleExtension(trait: WebRtcLiveView, mediaSessionId: String, liveSessionDurationSeconds: UShort ) {
  delay(liveSessionDurationSeconds - BUFFER_SECONDS * 1000)
  val response = trait.extendLiveView(mediaSessionId)
  // returns how long the session will be live for
  return response.liveSessionDurationSeconds
}

টকব্যাক শুরু করুন এবং বন্ধ করুন

টকব্যাক শুরু করতে, WebRtcLiveView বৈশিষ্ট্যের startTalkback() পদ্ধতিটি কল করুন। থামাতে, stopTalkback() ব্যবহার করুন।

// Make sure camera stream is on
suspend fun setTalkback(isOn: Boolean, trait: WebRtcLiveView, mediaSessionId: String) {
  if(isOn) {
    trait.startTalkback(mediaSessionId)
  } else {
    trait.stopTalkback(mediaSessionId)
  }
}

রেকর্ডিং ক্ষমতা সক্ষম এবং অক্ষম করুন

ক্যামেরার রেকর্ডিং ক্ষমতা সক্রিয় করতে, TransportStatusEnum.Active কে PushAvStreamTransport বৈশিষ্ট্যের setTransportStatus() পদ্ধতিতে পাস করুন। রেকর্ডিং ক্ষমতা অক্ষম করতে, এটি TransportStatusEnum.Inactive পাস করুন। নিম্নলিখিত উদাহরণে, আমরা এই কলগুলিকে একটি একক কলে মুড়ে ফেলি যা রেকর্ডিং ক্ষমতা টগল করার জন্য একটি Boolean ব্যবহার করে:

// Start or stop recording for all connections.
suspend fun setCameraRecording(isOn: Boolean) {
  val pushAvStreamTransport = getPushAvStreamTransport
  if(isOn) {
    pushAvStreamTransport.setTransportStatus(TransportStatusEnum.Active)
  } else {
    pushAvStreamTransport.setTransportStatus(TransportStatusEnum.Inactive)
  }
}

ক্যামেরার রেকর্ডিং ক্ষমতা সক্রিয় বা নিষ্ক্রিয় করা ক্যামেরার ভিডিও চালু বা বন্ধ করার মতোই। যখন একটি ক্যামেরার ভিডিও চালু থাকে, তখন এটি রেকর্ডিং হয় (ইভেন্ট এবং সম্পর্কিত ক্লিপগুলির উদ্দেশ্যে)।

যখন রেকর্ডিং ক্ষমতা অক্ষম থাকে (ক্যামেরা ভিডিও বন্ধ থাকে):

  • ডিভাইসের ধরণের connectivityState অনুসারে ক্যামেরাটি এখনও অনলাইনে দেখাতে পারে।
  • লাইভস্ট্রিমটি অ্যাক্সেস করা যাচ্ছে না, এবং ক্যামেরা কোনও ক্লাউড ইভেন্ট সনাক্ত করতে পারে না।

রেকর্ডিং ক্ষমতা সক্রিয় আছে কিনা তা পরীক্ষা করুন

ক্যামেরার রেকর্ডিং ক্ষমতা সক্রিয় কিনা তা নির্ধারণ করতে, কোনও সংযোগ সক্রিয় আছে কিনা তা পরীক্ষা করে দেখুন। নিম্নলিখিত উদাহরণটি এটি করার জন্য দুটি ফাংশন সংজ্ঞায়িত করে:

// Get the on/off state
suspend fun onOffState(cameraDevice: HomeDevice, cameraDeviceType) {
  // Query the device for pushAvStreamTransport
  val pushAvTrait = getPushAvStreamTransport()
  return pushAvTrait.recordModeActive()
}

// Check if the camera's recording capability is enabled
fun PushAvStreamTransport.recordModeActive(): Boolean {
  return currentConnections?.any { it.transportStatus == TransportStatusEnum.Active } ?: false
}

পরীক্ষা করার আরেকটি উপায় হল findTransport() ফাংশনটি একটি predicate সহ ব্যবহার করা:

// Fetch the current connections
suspend fun queryRecordModeState(cameraDevice: HomeDevice, cameraDeviceType) {
  val pushAvStreamTransport = getPushAvStreamTransport()
  return pushAvStreamTransport.findTransport().let {
      it.transportConfigurations.any { it.transportStatus == TransportStatusEnum.Active
    }
}

অডিও সেটিংস

হোম এপিআই-এর মাধ্যমে বিভিন্ন ক্যামেরা অডিও সেটিংস নিয়ন্ত্রণ করা যেতে পারে।

মাইক্রোফোন চালু বা বন্ধ করুন

ডিভাইসের মাইক্রোফোন চালু বা বন্ধ করতে, বিল্ট-ইন setMicrophoneMuted Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের microphoneMuted বৈশিষ্ট্যটি আপডেট করুন:

// Turn the device's microphone on or off
suspend fun turnOffMicrophone(disableMicrophone: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setMicrophoneMuted(disableMicrophone) }
}

অডিও রেকর্ডিং চালু বা বন্ধ করুন

ডিভাইসের জন্য অডিও রেকর্ডিং চালু বা বন্ধ করতে, বিল্ট-ইন setRecordingMicrophoneMuted Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের recordingMicrophoneMuted বৈশিষ্ট্যটি আপডেট করুন:

// Turn audio recording on or off for the device
suspend fun turnOffAudioRecording(disableAudioRecording: Boolean, trait: CameraAvStreamManagement) {
  trait.update { setRecordingMicrophoneMuted(disableAudioRecording) }
}

স্পিকারের ভলিউম সামঞ্জস্য করুন

ডিভাইসের জন্য স্পিকার ভলিউম সামঞ্জস্য করতে, বিল্ট-ইন setSpeakerVolumeLevel Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের speakerVolumeLevel বৈশিষ্ট্যটি আপডেট করুন:

// Adjust the camera speaker volume
suspend fun adjustSpeakerVolume(volume: Int, trait: CameraAvStreamManagement) {
  trait.update { setSpeakerVolumeLevel(volume.toUbyte()) }
}

অন্যান্য সেটিংস

হোম এপিআই-এর মাধ্যমে অন্যান্য বিভিন্ন ক্যামেরা সেটিংস নিয়ন্ত্রণ করা যেতে পারে।

ছবির ওরিয়েন্টেশন পরিবর্তন করুন

ক্যামেরার ছবির (ভিডিও) ওরিয়েন্টেশন ঘোরানো যেতে পারে। ভিডিওটি কেবল ১৮০ ডিগ্রি ঘোরানো যেতে পারে।

ক্যামেরার ছবির ওরিয়েন্টেশন পরিবর্তন করতে, বিল্ট-ইন setImageRotation Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের imageRotation বৈশিষ্ট্যটি আপডেট করুন:

// Change the camera's image orientation
val isRotated = false

cameraAvStreamManagement.update { setImageRotation(if (isRotated) 180.toUShort() else 0.toUShort()) }

নাইট ভিশন চালু বা বন্ধ করুন

ক্যামেরার জন্য নাইট ভিশন চালু বা বন্ধ করতে, বিল্ট-ইন setNightVision Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের nightVision বৈশিষ্ট্য আপডেট করতে TriStateAutoEnum ব্যবহার করুন:

// Turn night vision on
cameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.On)
}

// Turn night vision off
CameraAvStreamManagement.update {
  setNightVision(CameraAvStreamManagementTrait.TriStateAutoEnum.Off)
}

স্ট্যাটাস LED এর উজ্জ্বলতা পরিবর্তন করুন

স্ট্যাটাস LED এর উজ্জ্বলতা পরিবর্তন করতে, বিল্ট-ইন setStatusLightBrightness Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের statusLightBrightness বৈশিষ্ট্য আপডেট করতে ThreeLevelAutoEnum ব্যবহার করুন:

// Set the LED brightness to high
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.High)
}

// Set the LED brightness to low
cameraAvStreamManagement.update {
  setStatusLightBrightness(CameraAvStreamManagementTrait.ThreeLevelAutoEnum.Low)
}

ক্যামেরার ভিউপোর্ট পরিবর্তন করুন

ক্যামেরা ভিউপোর্টটি জুম এবং ক্রপ বৈশিষ্ট্যের মতোই যা জুম এবং এনহ্যান্স নেস্ট ক্যামেরা ভিডিও সাপোর্ট নিবন্ধে বর্ণিত হয়েছে।

ভিউপোর্টটি একটি ViewportStruct এ সংজ্ঞায়িত করা হয় যার চারটি মান থাকে, যা ভিউপোর্টের স্থানাঙ্ক হিসেবে ব্যবহৃত হয়। স্থানাঙ্কগুলি নিম্নরূপ সংজ্ঞায়িত করা হয়:

(x1,y1) -- (x2,y1)
   |          |
(x1,y2) -- (x2,y2)

ViewportStruct এর মান নির্ধারণ করা অ্যাপের UI এবং ক্যামেরা বাস্তবায়নের উপর নির্ভর করে। খুব মৌলিক স্তরে, ক্যামেরা ভিডিওর ভিউপোর্ট সেট করতে, বিল্ট-ইন setViewport Kotlin ফাংশন ব্যবহার করে CameraAvStreamManagement বৈশিষ্ট্যের viewport অ্যাট্রিবিউটটি ViewportStruct দিয়ে আপডেট করুন:

cameraAvStreamManagement
  .update { setViewport(
    CameraAvStreamManagementTrait.ViewportStruct(
      x1 = horizontalRange.rangeStart.roundToInt().toUShort(),
      x2 = horizontalRange.rangeEnd.roundToInt().toUShort(),
      y1 = verticalRange.rangeStart.roundToInt().toUShort(),
      y2 = verticalRange.rangeEnd.roundToInt().toUShort(),
    )
) }

ডিভাইসের জাগরণ সংবেদনশীলতা সামঞ্জস্য করুন

ডিভাইসটির জেগে ওঠার সংবেদনশীলতা ব্যাটারি সংরক্ষণের জন্য ব্যবহৃত হয়, ডিভাইসটি যে পরিসরের কার্যকলাপ অনুভব করতে পারে তা হ্রাস করে এবং সেই কার্যকলাপ সনাক্ত করার পরে ঘুম থেকে ওঠার সময় বাড়িয়ে।

হোম এপিআইগুলিতে, ডিভাইসের transportOptionstriggerOptions এর motionSensitivity বৈশিষ্ট্য ব্যবহার করে এটি সেট করা যেতে পারে। এই বিকল্পগুলি প্রতিটি ডিভাইসের জন্য PushAvStreamTransport বৈশিষ্ট্যের মধ্যে সংজ্ঞায়িত করা হয়।

জাগরণ সংবেদনশীলতা শুধুমাত্র নিম্নলিখিত মানগুলিতে সেট করা যেতে পারে:

  • ১ = কম
  • ৫ = মাঝারি
  • ১০ = উচ্চ

আপডেট করার প্রক্রিয়া হল findTransport কমান্ড ব্যবহার করে সক্রিয় রেকর্ডিং স্ট্রিমগুলির জন্য পরিবহন কনফিগারেশন খুঁজে বের করা, তারপর modifyPushTransport কমান্ড ব্যবহার করে নতুন সংবেদনশীলতা মান দিয়ে কনফিগারেশনটি পরিবর্তন করা:

// Create a struct with the new wake-up sensitivity
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionSensitivity =
        OptionalValue.present(wakeUpSensitivity.toUByte())
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }

ইভেন্টের সর্বোচ্চ দৈর্ঘ্য সামঞ্জস্য করুন

সর্বাধিক ইভেন্ট দৈর্ঘ্য হল ক্যামেরাটি একটি ইভেন্টের জন্য একটি ক্লিপ রেকর্ড করার সময়কাল। হোম API গুলির মাধ্যমে এটি প্রতি ডিভাইসে, GHA এর মতো একই দৈর্ঘ্যে, সেকেন্ডের ব্যবধানে কনফিগার করা যেতে পারে:

  • ১০ সেকেন্ড
  • ১৫ সেকেন্ড
  • ৩০ সেকেন্ড
  • ৬০ সেকেন্ড (১ মিনিট)
  • ১২০ সেকেন্ড (২ মিনিট)
  • ১৮০ সেকেন্ড (৩ মিনিট)

হোম এপিআইগুলিতে, এটি ডিভাইসের transportOptionstriggerOptions এর motionTimeControl বৈশিষ্ট্য ব্যবহার করে সেট করা যেতে পারে। এই বিকল্পগুলি প্রতিটি ডিভাইসের জন্য PushAvStreamTransport বৈশিষ্ট্যের মধ্যে সংজ্ঞায়িত করা হয়।

আপডেট করার প্রক্রিয়া হল findTransport কমান্ড ব্যবহার করে সক্রিয় রেকর্ডিং স্ট্রিমগুলির জন্য পরিবহন কনফিগারেশন খুঁজে বের করা, তারপর modifyPushTransport কমান্ড ব্যবহার করে নতুন ইভেন্ট দৈর্ঘ্যের মান দিয়ে কনফিগারেশনটি পরিবর্তন করা:

// Create a struct with the new max event length
// where maxDuration is the length in seconds
val toUpdate =  TransportOptionsStruct(
  triggerOptions =
    TransportTriggerOptionsStruct(
      motionTimeControl =
        OptionalValue.present(
          TransportMotionTriggerTimeControlStruct(maxDuration = it.toUInt())
        )
    )
  )

// Get the configurations for active connections
val connections  = pushAvStreamTransport.findTransport().transportConfigurations
  // Update all recording streams with the new transport options.
  for (connection in connections) {
    if (connection.transportOptions.getOrNull()?.streamUsage == StreamUsageEnum.Recording) {
      trait.modifyPushTransport(
        connectionId = connection.connectionId,
        transportOptions = toUpdate,
      )
    }
  }