ক্যামেরাএক্স ভিডিও ক্যাপচারিং আর্কিটেকচার

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

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

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

ধারণাগত চিত্র যা দেখায় যে ক্যামেরা x কীভাবে ভিডিও ক্যাপচার ব্যবহারের ক্ষেত্রে পরিচালনা করে
চিত্র ২। ধারণাগত চিত্র যা দেখায় যে ক্যামেরাএক্স কীভাবে VideoCapture ব্যবহারের ক্ষেত্রে পরিচালনা করে।

চিত্র ২-এ দেখানো হয়েছে, ক্যামেরাএক্স ভিডিও ক্যাপচারে কয়েকটি উচ্চ-স্তরের স্থাপত্য উপাদান রয়েছে:

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

ভিডিওক্যাপচার এপিআই জটিল ক্যাপচারিং ইঞ্জিনকে বিমূর্ত করে এবং অ্যাপ্লিকেশনগুলিকে অনেক সহজ এবং সরল API প্রদান করে।

ভিডিওক্যাপচার এপিআই ওভারভিউ

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

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

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

চিত্র ৩ এই বস্তুগুলির মধ্যে সম্পর্ক দেখায়:

একটি ভিডিওতে সংঘটিত মিথস্ক্রিয়াগুলি দেখানো চিত্র ক্যাপচার ব্যবহারের ক্ষেত্রে
চিত্র ৩। ভিডিওক্যাপচার ব্যবহারের ক্ষেত্রে সংঘটিত মিথস্ক্রিয়াগুলি দেখানো চিত্র।

কিংবদন্তি:

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

বিস্তারিত API তালিকাটি সোর্স কোডের ভিতরে current.txt ফাইলে রয়েছে।

ভিডিওক্যাপচার API ব্যবহার করা হচ্ছে

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

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

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

ভিডিওক্যাপচার বাঁধুন

VideoCapture ব্যবহারের ক্ষেত্রে আবদ্ধ করতে, নিম্নলিখিতগুলি করুন:

  1. একটি Recorder অবজেক্ট তৈরি করুন।
  2. VideoCapture অবজেক্ট তৈরি করুন।
  3. একটি Lifecycle সাথে আবদ্ধ হন।

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

ক্যামেরাএক্স Recorder ভিডিও রেজোলিউশনের জন্য নিম্নলিখিত পূর্বনির্ধারিত Qualities সমর্থন করে:

  • 4K আল্ট্রা এইচডি ভিডিও সাইজের (2160p) জন্য Quality.UHD
  • পূর্ণ এইচডি ভিডিও আকারের জন্য Quality.FHD । FHD (1080p)
  • HD ভিডিও সাইজের জন্য Quality.HD (720p)
  • Quality.SD ভিডিও সাইজের জন্য এসডি (৪৮০পি)

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

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

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

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

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

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

    val cameraInfo = cameraProvider.availableCameraInfos.filter {
        Camera2CameraInfo
        .from(it)
        .getCameraCharacteristic(CameraCharacteristics.LENS\_FACING) == CameraMetadata.LENS_FACING_BACK
    }
    
    val supportedQualities = QualitySelector.getSupportedQualities(cameraInfo[0])
    val filteredQualities = arrayListOf (Quality.UHD, Quality.FHD, Quality.HD, Quality.SD)
                           .filter { supportedQualities.contains(it) }
    
    // Use a simple ListView with the id of simple_quality_list_view
    viewBinding.simpleQualityListView.apply {
        adapter = ArrayAdapter(context,
                               android.R.layout.simple_list_item_1,
                               filteredQualities.map { it.qualityToString() })
    
        // Set up the user interaction to manually show or hide the system UI.
        setOnItemClickListener { _, _, position, _ ->
            // Inside View.OnClickListener,
            // convert Quality.* constant to QualitySelector
            val qualitySelector = QualitySelector.from(filteredQualities[position])
    
            // Create a new Recorder/VideoCapture for the new quality
            // and bind to lifecycle
            val recorder = Recorder.Builder()
                .setQualitySelector(qualitySelector).build()
    
             // ...
        }
    }
    
    // A helper function to translate Quality to a string
    fun Quality.qualityToString() : String {
        return when (this) {
            Quality.UHD -> "UHD"
            Quality.FHD -> "FHD"
            Quality.HD -> "HD"
            Quality.SD -> "SD"
            else -> throw IllegalArgumentException()
        }
    }
    
    

    মনে রাখবেন যে QualitySelector.getSupportedQualities() থেকে ফিরে আসা ক্ষমতাটি VideoCapture ব্যবহারের ক্ষেত্রে অথবা 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 অবজেক্টে Recording.stop() অথবা Recording.close() কল করার পরে আপনি একটি নতুন রেকর্ডিং শুরু করতে পারেন।

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

  • FileDescriptorOutputOptions একটি FileDescriptor এ ক্যাপচার করার জন্য বিকল্প।
  • File ক্যাপচার করার জন্য FileOutputOptions
  • MediaStoreOutputOptions একটি MediaStore এ ক্যাপচার করার জন্য বিকল্প।

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

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

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

  • withAudioEnabled() দিয়ে অডিও সক্ষম করুন।
  • start(Executor, Consumer<VideoRecordEvent>) দিয়ে ভিডিও রেকর্ডিং ইভেন্ট পেতে একজন শ্রোতাকে নিবন্ধন করুন।
  • 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);

জাভা

Recorder.Builder builder = new Recorder.Builder();
if (mVideoQuality != QUALITY_AUTO) {
    builder.setQualitySelector(
        QualitySelector.from(mVideoQuality));
}
  VideoCapture<Recorder> videoCapture = new VideoCapture.Builder<>(builder.build())
      .setMirrorMode(MIRROR_MODE_ON_FRONT_ONLY)
      .build();
    useCases.add(videoCapture);

একটি সক্রিয় রেকর্ডিং নিয়ন্ত্রণ করুন

আপনি নিম্নলিখিত পদ্ধতিগুলি ব্যবহার করে চলমান 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 এ নির্দিষ্ট অবস্থান থেকে ক্যাপচার করা ভিডিওটি অ্যাক্সেস করতে পারবেন।

অতিরিক্ত সম্পদ

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