CameraX ভিডিও ক্যাপচারিং আর্কিটেকচার

ক্যাপচারিং সিস্টেম সাধারণত ভিডিও ও অডিও স্ট্রিম রেকর্ড করে, সেগুলি কম্প্রেস করে, দুটি স্ট্রিম মিক্স করে, তারপর ফলাফল হিসেবে পাওয়া স্ট্রিম ডিস্কে লিখে রাখে।

ভিডিও এবং অডিও ক্যাপচারিং সিস্টেমের জন্য ধারণাগত ডায়াগ্রাম
ছবি ১. ভিডিও ও অডিও ক্যাপচারিং সিস্টেমের জন্য ধারণাগত ডায়াগ্রাম।

CameraX-এ, ভিডিও ক্যাপচার করার সমাধান হল VideoCapture ব্যবহারের ক্ষেত্র:

কনসেপ্টুয়াল ডায়াগ্রাম যা দেখায় যে কীভাবে ক্যামেরা x ভিডিও ক্যাপচার
         ব্যবহারের কেস হ্যান্ডেল করে
ছবি ২. কনসেপচুয়াল ডায়াগ্রাম যা দেখায় যে CameraX কীভাবে VideoCapture ব্যবহারের কেস ম্যানেজ করে।

ছবি ২-এ যেমন দেখানো হয়েছে, CameraX ভিডিও ক্যাপচারে কয়েকটি হাই-লেভেল আর্কিটেকচারাল কম্পোনেন্ট অন্তর্ভুক্ত:

  • ভিডিও সোর্সের জন্য SurfaceProvider।
  • অডিও সোর্সের জন্য AudioSource।
  • ভিডিও/অডিও এনকোড ও কম্প্রেস করার জন্য দুটি এনকোডার।
  • দুটি স্ট্রিম মাক্স করার জন্য একটি মিডিয়া মাক্সার।
  • ফলাফল লেখার জন্য ফাইল সেভার।

VideoCapture API জটিল ক্যাপচারিং ইঞ্জিনকে অ্যাবস্ট্র্যাক্ট করে এবং অ্যাপ্লিকেশনগুলিকে অনেক সহজ এবং সরল API প্রদান করে।

VideoCapture API ওভারভিউ

VideoCapture হল CameraX-এর একটি ব্যবহারের উদাহরণ যা নিজে থেকে বা অন্যান্য ব্যবহারের উদাহরণের সাথে একত্রিত হলে ভাল কাজ করে। নির্দিষ্ট কাজ করে এমন কম্বিনেশন ক্যামেরার হার্ডওয়্যার ক্ষমতার উপর নির্ভর করে, তবে Preview এবং VideoCapture হল সব ডিভাইসে কাজ করে এমন কম্বিনেশন।

VideoCapture API-তে নিম্নলিখিত অবজেক্ট থাকে যা অ্যাপ্লিকেশনের সাথে যোগাযোগ করে:

  • VideoCapture হল টপ-লেভেল ইউজ কেস ক্লাস। VideoCapture, CameraSelector সহ LifecycleOwner এবং অন্যান্য CameraX UseCases-এর সাথে বাইন্ড করে। এইসব ধারণা ও ব্যবহার সম্পর্কে আরও জানতে, CameraX আর্কিটেকচার দেখুন।
  • Recorder হল VideoOutput-এর একটি ইমপ্লিমেন্টেশন যা VideoCapture-এর সাথে ঘনিষ্ঠভাবে যুক্ত। Recorder ভিডিও ও অডিও ক্যাপচার করার জন্য ব্যবহার করা হয়। একটি অ্যাপ্লিকেশন Recorder থেকে রেকর্ডিং তৈরি করে।
  • PendingRecording রেকর্ডিং কনফিগার করে, অডিও চালু করা এবং ইভেন্ট লিসনার সেট করার মতো বিকল্প প্রদান করে। PendingRecording তৈরি করতে আপনাকে অবশ্যই Recorder ব্যবহার করতে হবে। PendingRecording কোনও কিছু রেকর্ড করে না।
  • Recording-এর মাধ্যমে আসল রেকর্ডিং করা হয়। Recording তৈরি করতে আপনাকে অবশ্যই PendingRecording ব্যবহার করতে হবে।

ছবি ৩-এ এইসব অবজেক্টের মধ্যে সম্পর্ক দেখানো হয়েছে:

ভিডিও ক্যাপচার ব্যবহারের ক্ষেত্রে যে ইন্টার‍্যাকশন হয় তা ডায়াগ্রামের মাধ্যমে দেখানো হয়েছে
ছবি ৩. VideoCapture ব্যবহারের ক্ষেত্রে যেসব ইন্টার‍্যাকশন হয় তা ডায়াগ্রামের মাধ্যমে দেখানো হয়েছে।

লিজেন্ড:

  1. QualitySelector-এর সাথে Recorder তৈরি করুন।
  2. Recorder-এর সাথে এগুলির মধ্যে কোনও একটি কনফিগার করুন: OutputOptions।
  3. প্রয়োজন হলে withAudioEnabled() দিয়ে অডিও চালু করুন।
  4. রেকর্ডিং শুরু করতে VideoRecordEvent শ্রোতার সাথে start()-এ কল করুন।
  5. রেকর্ডিং কন্ট্রোল করতে Recording-এ pause()/resume()/stop() ব্যবহার করুন।
  6. আপনার ইভেন্ট লিসনারের মধ্যে VideoRecordEvents-এর উত্তর দিন।

API-এর বিস্তারিত তালিকা সোর্স কোডের মধ্যে current.txt-এ আছে।

VideoCapture API ব্যবহার করা

আপনার অ্যাপে CameraX VideoCapture ব্যবহারের কেস ইন্টিগ্রেট করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. VideoCapture বাইন্ড করুন।
  2. রেকর্ডিং প্রস্তুত ও কনফিগার করুন।
  3. রানটাইম রেকর্ডিং শুরু ও নিয়ন্ত্রণ করুন।

এন্ড-টু-এন্ড রেকর্ডিং সেশন পেতে, প্রতিটি ধাপে আপনি কী করতে পারেন তা নিম্নলিখিত বিভাগে আউটলাইন করা হয়েছে।

VideoCapture বাইন্ড করুন

VideoCapture ব্যবহারের কেস বাইন্ড করতে, নিম্নলিখিত ধাপগুলি অনুসরণ করুন:

  1. Recorder অবজেক্ট তৈরি করুন।
  2. VideoCapture অবজেক্ট তৈরি করুন।
  3. Lifecycle-এ বাইন্ড করুন।

CameraX VideoCapture API বিল্ডার ডিজাইন প্যাটার্ন অনুসরণ করে। অ্যাপ্লিকেশন Recorder তৈরি করতে Recorder.Builder ব্যবহার করুন। এছাড়াও, আপনি QualitySelector অবজেক্টের মাধ্যমে Recorder-এর জন্য ভিডিও রেজোলিউশন কনফিগার করতে পারবেন।

CameraX Recorder ভিডিও রেজোলিউশনের জন্য নিম্নলিখিত আগে থেকে নির্ধারিত Qualities সাপোর্ট করে:

  • 4K আল্ট্রা এইচডি ভিডিও সাইজের (2160p) জন্য Quality.UHD
  • Quality.QHD কোয়াড HD ভিডিও সাইজের (1440p) জন্য, CameraX-এ চালু করা হয়েছে 1.7.0-alpha02
  • ফুল HD ভিডিও সাইজের (1080p) জন্য Quality.FHD
  • HD ভিডিও সাইজের (720p) জন্য Quality.HD
  • SD ভিডিও সাইজের (480p) জন্য Quality.SD

মনে রাখবেন যে অ্যাপের মাধ্যমে অনুমোদিত হলে CameraX অন্যান্য রেজোলিউশনও বেছে নিতে পারে।

প্রতিটি বিকল্পের জন্য ভিডিওর সঠিক সাইজ ক্যামেরা ও এনকোডারের ক্ষমতার উপর নির্ভর করে। আরও তথ্যের জন্য, CamcorderProfile-এর ডকুমেন্টেশন দেখুন।

অ্যাপ্লিকেশনগুলি একটি QualitySelector তৈরি করে রেজোলিউশন কনফিগার করতে পারে। আপনি নিম্নলিখিত পদ্ধতির মধ্যে যেকোনও একটি ব্যবহার করে QualitySelector তৈরি করতে পারবেন:

  • fromOrderedList ব্যবহার করে কয়েকটি পছন্দের রেজোলিউশন প্রদান করুন এবং পছন্দের রেজোলিউশনের কোনওটিই কাজ না করলে ব্যবহার করার জন্য একটি ফলব্যাক স্ট্র্যাটেজি অন্তর্ভুক্ত করুন।

    CameraX বেছে নেওয়া ক্যামেরার ক্ষমতার উপর ভিত্তি করে সেরা ফলব্যাক ম্যাচ নির্ধারণ করতে পারে, আরও বিবরণের জন্য QualitySelector-এর FallbackStrategy specification দেখুন। যেমন, নিম্নলিখিত কোড রেকর্ডিংয়ের জন্য সবচেয়ে বেশি রেজোলিউশনের অনুরোধ করে, এবং অনুরোধ করা রেজোলিউশনের কোনওটিই কাজ না করলে, CameraX-কে Quality.SD রেজোলিউশনের সবচেয়ে কাছাকাছি একটি রেজোলিউশন বেছে নেওয়ার অনুমতি দেয়:

    val qualitySelector = QualitySelector.fromOrderedList(
             listOf(Quality.UHD, Quality.QHD, Quality.FHD, Quality.HD, Quality.SD),
             FallbackStrategy.lowerQualityOrHigherThan(Quality.SD))
    
  • প্রথমে ক্যামেরার ক্ষমতা সম্পর্কে কোয়েরি করুন এবং QualitySelector.from ব্যবহার করে কাজ করে এমন রেজোলিউশন থেকে বেছে নিন:

    val cameraInfo = cameraProvider.availableCameraInfos.filter {
        it.cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) ==
            CameraMetadata.LENS_FACING_BACK
    }
    
    // Filter to SDR resolutions supported by both the camera sensor and Recorder
    // encoder so the UI picker only displays valid options.
    val supportedQualities =
        Recorder.getVideoCapabilities(cameraInfo[0]).getSupportedQualities(DynamicRange.SDR)
    val filteredQualities = arrayListOf (Quality.UHD, Quality.QHD, Quality.FHD, Quality.HD, Quality.SD)
                           .filter { supportedQualities.contains(it) }
    
    viewBinding.simpleQualityListView.apply {
        adapter = ArrayAdapter(context,
                               android.R.layout.simple_list_item_1,
                               filteredQualities.map { it.qualityToString() })
    
        setOnItemClickListener { _, _, position, _ ->
            // QualitySelector is configured at Recorder build time, so selecting
            // a new resolution requires building a new Recorder instance.
            val qualitySelector = QualitySelector.from(filteredQualities[position])
    
            val recorder = Recorder.Builder()
                .setQualitySelector(qualitySelector).build()
    
             // ...
        }
    }
    
    fun Quality.qualityToString() : String {
        return when (this) {
            Quality.UHD -> "UHD"
            Quality.QHD -> "QHD"
            Quality.FHD -> "FHD"
            Quality.HD -> "HD"
            Quality.SD -> "SD"
            else -> throw IllegalArgumentException()
        }
    }
    
    

    VideoCapabilities.getSupportedQualities (থেকে Recorder.getVideoCapabilities এর জন্য DynamicRange.SDR) দ্বারা ফেরত দেওয়া প্রতিটি Quality VideoCapture ব্যবহারের ক্ষেত্রে একা বা Preview ব্যবহারের ক্ষেত্রের সাথে একসাথে কাজ করে। আপনি যদি ImageCapture বা ImageAnalysis-এর সাথেও বাইন্ড করেন, তাহলে ক্যামেরা সেই কম্বিনেশন সাপোর্ট না করলে CameraX বাইন্ড করতে পারবে না।

আপনার কাছে QualitySelector থাকলে, অ্যাপ্লিকেশনটি একটি VideoCapture অবজেক্ট তৈরি করতে এবং বাইন্ডিং করতে পারে। মনে রাখবেন যে এই বাইন্ডিং অন্যান্য ব্যবহারের ক্ষেত্রে একই রকম:

val recorder = Recorder.Builder()
    .setExecutor(cameraExecutor).setQualitySelector(qualitySelector)
    .build()
val videoCapture = VideoCapture.withOutput(recorder)

try {
    // Bind use cases to camera.
    cameraProvider.bindToLifecycle(
        this, CameraSelector.DEFAULT_BACK_CAMERA, preview, videoCapture
    )
} catch (exc: Exception) {
    Log.e(TAG, "Use case binding failed", exc)
}

মনে রাখবেন যে bindToLifecycle(), Camera অবজেক্ট রিটার্ন করে। জুম ও এক্সপোজারের মতো ক্যামেরা আউটপুট নিয়ন্ত্রণ করার ব্যাপারে আরও তথ্যের জন্য এই নির্দেশিকা দেখুন।

Recorder সিস্টেমের জন্য সবচেয়ে উপযুক্ত ফর্ম্যাট বেছে নেয়। সবচেয়ে সাধারণ ভিডিও কোডেক হল H.264 AVC) এবং কন্টেনার ফর্ম্যাট হল MPEG-4।

কনফিগার ও রেকর্ডিং তৈরি করুন

Recorder থেকে, অ্যাপ্লিকেশনটি ভিডিও এবং অডিও ক্যাপচার করার জন্য রেকর্ডিং অবজেক্ট তৈরি করতে পারে। অ্যাপ্লিকেশন নিম্নলিখিত কাজগুলি করে রেকর্ডিং তৈরি করে:

  1. prepareRecording()-এর সাথে OutputOptions কনফিগার করুন।
  2. (ঐচ্ছিক) অডিও রেকর্ডিং চালু করুন।
  3. VideoRecordEvent লিসেনার রেজিস্টার করতে এবং ভিডিও ক্যাপচার করা শুরু করতে start() ব্যবহার করুন।

আপনি start() ফাংশন কল করলে, Recorder একটি Recording অবজেক্ট রিটার্ন করে। আপনার অ্যাপ্লিকেশন এই Recording অবজেক্ট ব্যবহার করে ক্যাপচার করা শেষ করতে বা পজ বা আবার চালু করার মতো অন্যান্য অ্যাকশন পারফর্ম করতে পারে।

একটি Recorder একবারে একটি Recording অবজেক্ট সাপোর্ট করে। আপনি Recording.stop() বা Recording.close()-এ কল করার পরে আগের Recording অবজেক্টে নতুন রেকর্ডিং শুরু করতে পারবেন।

আসুন, এই ধাপগুলি আরও বিস্তারিতভাবে দেখি। প্রথমে, অ্যাপ্লিকেশনটি Recorder.prepareRecording() সহ রেকর্ডারের জন্য OutputOptions কনফিগার করে। Recorder-এ এই ধরনের OutputOptions কাজ করে:

  • FileDescriptorOutputOptions-এ ক্যাপচার করার জন্য FileDescriptor।
  • FileOutputOptions File-এ ক্যাপচার করার জন্য।
  • MediaStoreOutputOptions-এ ক্যাপচার করার জন্য MediaStore।

সব OutputOptions ধরনের ফাইল আপনাকে setFileSizeLimit()-এর মাধ্যমে সর্বাধিক ফাইলের সাইজ সেট করতে দেয়। অন্যান্য বিকল্পগুলি নির্দিষ্ট আউটপুট ধরনের জন্য প্রযোজ্য, যেমন FileDescriptorOutputOptions-এর জন্য ParcelFileDescriptor।

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

অ্যাপ্লিকেশন রেকর্ডিং আরও কনফিগার করতে পারে, যেমন:

  • withAudioEnabled()-এর সাথে অডিও চালু করুন।
  • start(Executor, Consumer<VideoRecordEvent>)-এর মাধ্যমে ভিডিও রেকর্ডিং ইভেন্ট পেতে একজন লিসেনার রেজিস্টার করুন।
  • VideoCapture যে ক্যামেরার সাথে অ্যাটাচ করা আছে সেটি অন্য ক্যামেরার সাথে রিবাইন্ড করা হলে, PendingRecording.asPersistentRecording()-এর সাহায্যে রেকর্ডিং একটানা চালিয়ে যাওয়ার অনুমতি দিন।

রেকর্ডিং শুরু করতে, PendingRecording.start() নম্বরে কল করুন। CameraX PendingRecording-কে Recording-এ পরিবর্তন করে, রেকর্ডিংয়ের অনুরোধ সারিতে রাখে এবং নতুন তৈরি করা Recording অবজেক্ট অ্যাপ্লিকেশনকে ফেরত দেয়। সংশ্লিষ্ট ক্যামেরা ডিভাইসে রেকর্ডিং শুরু হলে, CameraX একটি VideoRecordEvent.EVENT_TYPE_START ইভেন্ট পাঠায়।

নিম্নলিখিত উদাহরণে দেখানো হয়েছে যে কীভাবে MediaStore ফাইলে ভিডিও ও অডিও রেকর্ড করতে হয়:

// Create MediaStoreOutputOptions for our recorder.
val name = "CameraX-recording-" +
    SimpleDateFormat(FILENAME_FORMAT, Locale.US)
        .format(System.currentTimeMillis()) + ".mp4"
val contentValues = ContentValues().apply {
    put(MediaStore.Video.Media.DISPLAY_NAME, name)
}
val mediaStoreOutput = MediaStoreOutputOptions.Builder(
    this.contentResolver,
    MediaStore.Video.Media.EXTERNAL_CONTENT_URI
)
    .setContentValues(contentValues)
    .build()

// 2. Configure Recorder and Start recording to the mediaStoreOutput.
val recording = videoCapture.output
    .prepareRecording(context, mediaStoreOutput)
    .withAudioEnabled()
    .start(ContextCompat.getMainExecutor(this), captureListener)

ডিফল্ট হিসেবে ফ্রন্ট ক্যামেরায় ক্যামেরা প্রিভিউ মিরর করা থাকলেও, VideoCapture-এর মাধ্যমে রেকর্ড করা ভিডিও ডিফল্ট হিসেবে মিরর করা থাকে না। CameraX 1.3-এর মাধ্যমে, এখন ভিডিও রেকর্ডিং মিরর করা সম্ভব যাতে ফ্রন্ট ক্যামেরা প্রিভিউ এবং রেকর্ড করা ভিডিও ম্যাচ করে।

MirrorMode-এর তিনটি বিকল্প আছে: MIRROR_MODE_OFF, MIRROR_MODE_ON এবং MIRROR_MODE_ON_FRONT_ONLY. ক্যামেরা প্রিভিউয়ের সাথে অ্যালাইন করতে, Google, MIROR_MODE_ON_FRONT_ONLY ব্যবহার করার সাজেশন দেয়, যার অর্থ হল রিয়ার ক্যামেরার জন্য মিররিং চালু করা নেই, তবে ফ্রন্ট ক্যামেরার জন্য চালু করা আছে। MirrorMode সম্পর্কে আরও তথ্যের জন্য, MirrorMode constants দেখুন।

এই কোড স্নিপেট দেখায় যে কীভাবে MIRROR_MODE_ON_FRONT_ONLY ব্যবহার করে VideoCapture.Builder.setMirrorMode() কল করতে হয়। আরও তথ্যের জন্য, setMirrorMode() দেখুন।

val recorder = Recorder.Builder().build()

val videoCapture = VideoCapture.Builder(recorder)
    .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY)
    .build()

useCases.add(videoCapture)

ডায়নামিক রেঞ্জ (HDR ভিডিও)

CameraX-এ DynamicRange ব্যবহার করে ১০-বিট হাই ডায়নামিক রেঞ্জ (HDR) ভিডিও রেকর্ডিং করা যায়, যেমন HLG10, HDR10, HDR10+ বা Dolby Vision।

HDR ভিডিও রেকর্ডিং ব্যবহার করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:

  1. VideoCapabilities.getSupportedDynamicRanges() ব্যবহার করে ক্যামেরার কাজ করে এমন ডায়নামিক রেঞ্জ কোয়েরি করুন।
  2. ঐচ্ছিক: আপনি কাস্টম QualitySelector কনফিগার করলে, getSupportedQualities(DynamicRange) ব্যবহার করে সেই ডায়নামিক রেঞ্জের জন্য কোন কোন কোয়ালিটি সাপোর্ট করে তা চেক করুন।
  3. setDynamicRange()-এর সাথে VideoCapture.Builder কনফিগার করুন।

ক্যামেরায় কাজ করলে নিম্নলিখিত উদাহরণ HLG ১০-বিট HDR রেকর্ডিং চালু করে:

Kotlin

val videoCapabilities = Recorder.getVideoCapabilities(cameraInfo)
val supportedHdrRanges = videoCapabilities.supportedDynamicRanges
    .filter { it != DynamicRange.SDR }

val recorder = Recorder.Builder().build()
val videoCapture = VideoCapture.Builder(recorder)
    .apply {
        if (supportedHdrRanges.contains(DynamicRange.HLG_10_BIT)) {
            setDynamicRange(DynamicRange.HLG_10_BIT)
        }
    }
    .build()

জাভা

VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(cameraInfo);
Set<DynamicRange> supportedRanges = videoCapabilities.getSupportedDynamicRanges();

Recorder recorder = new Recorder.Builder().build();
VideoCapture.Builder<Recorder> builder = new VideoCapture.Builder<>(recorder);
if (supportedRanges.contains(DynamicRange.HLG_10_BIT)) {
    builder.setDynamicRange(DynamicRange.HLG_10_BIT);
}
VideoCapture<Recorder> videoCapture = builder.build();

ভিডিও স্টেবিলাইজেশন

ভিডিও রেকর্ডিংয়ের সময় হাত কাঁপা ও ঝাঁকুনি কমানোর জন্য CameraX-এ ভিডিও স্টেবিলাইজেশন ফিচার কাজ করে।

ভিডিও স্টেবিলাইজেশন চালু করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:

  1. ক্যামেরা ডিভাইসে VideoCapabilities.isStabilizationSupported() ব্যবহার করে স্টেবিলাইজেশন কাজ করে কিনা তা চেক করুন।
  2. setVideoStabilizationEnabled(true) ব্যবহার করে VideoCapture.Builder-এ এটি চালু করুন।

ক্যামেরায় স্টেবিলাইজেশন কাজ করলে নিম্নলিখিত উদাহরণটি তা চালু করে:

Kotlin

val videoCapabilities = Recorder.getVideoCapabilities(cameraInfo)
val videoCapture = VideoCapture.Builder(recorder)
    .setVideoStabilizationEnabled(videoCapabilities.isStabilizationSupported)
    .build()

জাভা

VideoCapabilities videoCapabilities = Recorder.getVideoCapabilities(cameraInfo);
VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(recorder)
    .setVideoStabilizationEnabled(videoCapabilities.isStabilizationSupported())
    .build();

অ্যাক্টিভ রেকর্ডিং কন্ট্রোল করা

আপনি নিম্নলিখিত পদ্ধতি ব্যবহার করে, চলমান Recording পজ, আবার চালু ও বন্ধ করতে পারবেন:

  • বর্তমানে অ্যাক্টিভ রেকর্ডিং পজ করতে pause বলুন।
  • resume() পজ করা অ্যাক্টিভ রেকর্ডিং আবার চালু করতে।
  • stop() রেকর্ডিং শেষ করতে এবং যেকোনও সংশ্লিষ্ট রেকর্ডিং অবজেক্ট ফ্ল্যাশ করতে।
  • mute() বর্তমান রেকর্ডিং মিউট বা আনমিউট করতে।

মনে রাখবেন, রেকর্ডিং পজ করা বা চালু থাকা অবস্থায় Recording বন্ধ করতে আপনি stop()-এ কল করতে পারেন।

আপনি যদি PendingRecording.start()-এর সাথে EventListener রেজিস্টার করে থাকেন, তাহলে Recording VideoRecordEvent ব্যবহার করে যোগাযোগ করে।

  • VideoRecordEvent.EVENT_TYPE_STATUS-এর মাধ্যমে বর্তমান ফাইলের সাইজ ও রেকর্ড করার সময়সীমার মতো পরিসংখ্যান রেকর্ড করা হয়।
  • VideoRecordEvent.EVENT_TYPE_FINALIZE রেকর্ডিংয়ের ফলাফল দেখানোর জন্য ব্যবহার করা হয় এবং এতে চূড়ান্ত ফাইলের URI-এর সাথে সম্পর্কিত যেকোনও সমস্যার তথ্য অন্তর্ভুক্ত থাকে।

আপনার অ্যাপ EVENT_TYPE_FINALIZE পেলে, যা রেকর্ডিং সেশন সফল হয়েছে বলে ইঙ্গিত করে, আপনি তখন OutputOptions-এ নির্দিষ্ট করা লোকেশন থেকে ক্যাপচার করা ভিডিও অ্যাক্সেস করতে পারবেন।

রিয়েল-টাইম অডিও অ্যামপ্লিচিউড ও স্ট্যাটাস

রেকর্ডিং চলাকালীন, VideoRecordEvent.Status ইভেন্ট AudioStats-এর মাধ্যমে রিয়েল-টাইম অডিও পরিসংখ্যান প্রদান করে:

  • AudioStats.getAudioAmplitude() বর্তমান অডিও পিক অ্যামপ্লিটিউড ফেরত দেয়, যার রেঞ্জ 0.0 থেকে 1.0 পর্যন্ত। UI মিটার বা অডিও ওয়েভফর্ম ভিজ্যুয়ালাইজার চালানোর জন্য আপনি এই ভ্যালু ব্যবহার করতে পারবেন।
  • AudioStats.getAudioState() অডিও স্ট্রিমের বর্তমান স্ট্যাটাস দেখায়, যেমন AUDIO_STATE_ACTIVE, AUDIO_STATE_MUTED বা AUDIO_STATE_SOURCE_SILENCED।

নিম্নলিখিত উদাহরণটি একটি স্ট্যাটাস ইভেন্ট থেকে অডিওর বিস্তার পড়ে:

Kotlin

when (event) {
    is VideoRecordEvent.Status -> {
        val audioStats = event.recordingStats.audioStats
        if (audioStats.hasAudio()) {
            val amplitude = audioStats.audioAmplitude
            updateAudioWaveform(amplitude)
        }
    }
    // ...
}

জাভা

if (event instanceof VideoRecordEvent.Status) {
    VideoRecordEvent.Status status = (VideoRecordEvent.Status) event;
    AudioStats audioStats = status.getRecordingStats().getAudioStats();
    if (audioStats.hasAudio()) {
        double amplitude = audioStats.getAudioAmplitude();
        updateAudioWaveform(amplitude);
    }
}

হাই-স্পিড ও স্লো-মোশন ভিডিও

CameraX হাই-স্পিড ভিডিও রেকর্ডিং সাপোর্ট করে, যেমন ১২০, ২৪০ বা ৪৮০ fps, যা দুটি আলাদা ব্যবহারের ক্ষেত্রে সাহায্য করে:

  • হাই-ফ্রেম-রেট ভিডিও (প্লেয়ার-হ্যান্ডেলড স্লো মোশন): CameraX হাই ফ্রেম রেটে (যেমন, ১২০ fps) ফ্রেম ক্যাপচার ও সেভ করে। ভিডিও প্লেয়ার প্লেব্যাক স্পিড কন্ট্রোল করে, যার ফলে ব্যবহারকারী স্বাভাবিক স্পিড ও স্লো মোশনের মধ্যে টগল করতে বা ফ্রেম-বাই-ফ্রেম বিশ্লেষণ করতে পারেন।
  • চালানোর জন্য প্রস্তুত স্লো-মোশন ভিডিও: CameraX হাই-স্পিড স্ট্রিম প্রসেস করে এবং অ্যাডজাস্ট করা ফ্রেম টাইমস্ট্যাম্প সহ স্ট্যান্ডার্ড ৩০ fps ভিডিও ফাইল আউটপুট করে। স্লো-মোশন এফেক্ট "বেকেড ইন" করা থাকে, তাই ভিডিওটি কোনও বিশেষ প্লেয়ারের সহায়তা ছাড়াই যেকোনও স্ট্যান্ডার্ড প্লেয়ারে অটোমেটিক স্লো মোশনে চলে। যেমন, ১২০ fps-এ ক্যাপচার করা ভিডিও ৩০ fps-এ প্লেব্যাক করলে ১/৪x স্লো-মোশন ভিডিও তৈরি হয়।

হাই-স্পিড ক্ষমতা চেক করুন

হাই-স্পিড ভিডিও ক্যাপচার করার জন্য হার্ডওয়্যার সাপোর্ট এবং ডিভাইস প্রস্তুতকারকের থেকে সংশ্লিষ্ট CamcorderProfile সংজ্ঞা প্রয়োজন, যেমন CamcorderProfile.QUALITY_HIGH_SPEED_1080P বা QUALITY_HIGH_SPEED_720P।

হাই-স্পিড রেকর্ডিং কনফিগার করার আগে, Recorder.getHighSpeedVideoCapabilities(CameraInfo) ব্যবহার করে হাই-স্পিড ক্ষমতা কোয়েরি করুন:

Kotlin

val highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo)
if (highSpeedCapabilities == null) {
    // Camera does not support high-speed video capture
    return
}
val supportedQualities = highSpeedCapabilities.getSupportedQualities(DynamicRange.SDR)

জাভা

VideoCapabilities highSpeedCapabilities = Recorder.getHighSpeedVideoCapabilities(cameraInfo);
if (highSpeedCapabilities == null) {
    // Camera does not support high-speed video capture
    return;
}
List<Quality> supportedQualities = highSpeedCapabilities.getSupportedQualities(DynamicRange.SDR);

HighSpeedVideoSessionConfig কনফিগার করুন

হাই-স্পিড ক্যাপচার ব্যবহার করতে, VideoCapture এবং Preview ব্যবহারের ক্ষেত্র HighSpeedVideoSessionConfig-এ একত্রিত করুন। সেশন কনফিগার করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:

  1. VideoCapture-এর একটি ও Preview-এর একটি ব্যবহারিক উদাহরণ তৈরি করুন।
  2. VideoCapture ব্যবহারের ক্ষেত্রে HighSpeedVideoSessionConfig.Builder শুরু করুন এবং Preview অ্যাটাচ করুন।
  3. CameraInfo.getSupportedFrameRateRanges(SessionConfig) ব্যবহার করে কাজ করে এমন ফ্রেম রেটের রেঞ্জ কোয়েরি করুন এবং বেছে নেওয়া রেঞ্জ সেট করুন।
  4. হাই-ফ্রেম-রেট ভিডিও বা প্লে করার জন্য তৈরি স্লো-মোশন ভিডিওর মধ্যে থেকে বেছে নিন:
    • হাই-ফ্রেম-রেট ভিডিও তৈরি করতে, setSlowMotionEnabled(false) (ডিফল্ট) ছেড়ে দিন।
    • রেডি-টু-প্লে স্লো-মোশন ভিডিও তৈরি করতে, setSlowMotionEnabled(true) কল করুন।
  5. cameraProvider.bindToLifecycle() ব্যবহার করে সেশন কনফিগারেশন বাইন্ড করুন।

নিম্নলিখিত উদাহরণটি একটি রেডি-টু-প্লে স্লো-মোশন সেশন কনফিগার এবং বাইন্ড করে:

Kotlin

val preview = Preview.Builder().build()
val recorder = Recorder.Builder()
    .setQualitySelector(QualitySelector.from(supportedQualities.first()))
    .build()
val videoCapture = VideoCapture.withOutput(recorder)

// Build HighSpeedVideoSessionConfig
val sessionConfigBuilder = HighSpeedVideoSessionConfig.Builder(videoCapture)
    .setPreview(preview)
    // Enable automatic slow-motion playback at 30 fps
    .setSlowMotionEnabled(true)

// Query and set a supported high-speed frame rate range (such as 120 or 240 fps).
// The set is non-empty because getHighSpeedVideoCapabilities() returned non-null earlier.
val supportedFpsRanges = cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build())
sessionConfigBuilder.setFrameRateRange(supportedFpsRanges.first())

val sessionConfig = sessionConfigBuilder.build()

// Bind session config to lifecycle
cameraProvider.bindToLifecycle(
    lifecycleOwner,
    CameraSelector.DEFAULT_BACK_CAMERA,
    sessionConfig
)

জাভা

Preview preview = new Preview.Builder().build();
Recorder recorder = new Recorder.Builder()
    .setQualitySelector(QualitySelector.from(supportedQualities.get(0)))
    .build();
VideoCapture<Recorder> videoCapture = VideoCapture.withOutput(recorder);

HighSpeedVideoSessionConfig.Builder sessionConfigBuilder =
    new HighSpeedVideoSessionConfig.Builder(videoCapture)
        .setPreview(preview)
        .setSlowMotionEnabled(true);

// The set is non-empty because getHighSpeedVideoCapabilities() returned non-null earlier.
Set<Range<Integer>> supportedFpsRanges =
    cameraInfo.getSupportedFrameRateRanges(sessionConfigBuilder.build());
sessionConfigBuilder.setFrameRateRange(supportedFpsRanges.iterator().next());

HighSpeedVideoSessionConfig sessionConfig = sessionConfigBuilder.build();

cameraProvider.bindToLifecycle(
    lifecycleOwner,
    CameraSelector.DEFAULT_BACK_CAMERA,
    sessionConfig
);

এছাড়াও, আপনি Kotlin DSL ব্যবহার করতে পারেন, যা CameraX 1.7.0-alpha02-এ চালু করা হয়েছে, যাতে হাই-স্পিড সেশন সংক্ষেপে কনফিগার করা যায়:

val sessionConfig = highSpeedVideoSessionConfig(videoCapture) {
    this.preview = preview
    isSlowMotionEnabled = true
    frameRateRange = supportedFpsRanges.first()
}
cameraProvider.bindToLifecycle(
    lifecycleOwner,
    CameraSelector.DEFAULT_BACK_CAMERA,
    sessionConfig
)

হাই-স্পিড বা স্লো-মোশন ভিডিও রেকর্ড করা

HighSpeedVideoSessionConfig বাইন্ড করার পরে, স্ট্যান্ডার্ড ভিডিও রেকর্ডিংয়ের মতো একই পদ্ধতিতে VideoCapture ব্যবহার করে রেকর্ডিং শুরু করুন:

Kotlin

val recording = videoCapture.output
    .prepareRecording(context, mediaStoreOutput)
    .withAudioEnabled()
    .start(ContextCompat.getMainExecutor(context)) { event ->
        when (event) {
            is VideoRecordEvent.Start -> Log.d(TAG, "Recording started")
            is VideoRecordEvent.Finalize -> {
                if (!event.hasError()) {
                    Log.d(TAG, "Video saved: ${event.outputResults.outputUri}")
                }
            }
        }
    }

জাভা

Recording recording = videoCapture.getOutput()
    .prepareRecording(context, mediaStoreOutput)
    .withAudioEnabled()
    .start(ContextCompat.getMainExecutor(context), event -> {
        if (event instanceof VideoRecordEvent.Start) {
            Log.d(TAG, "Recording started");
        } else if (event instanceof VideoRecordEvent.Finalize) {
            VideoRecordEvent.Finalize finalize = (VideoRecordEvent.Finalize) event;
            if (!finalize.hasError()) {
                Log.d(TAG, "Video saved: " + finalize.getOutputResults().getOutputUri());
            }
        }
    });

অতিরিক্ত রিসোর্স

CameraX সম্পর্কে আরও জানতে, নিম্নলিখিত অতিরিক্ত রিসোর্স দেখুন: