ট্রান্সফর্মেশন

Jetpack Media3 Transformer Android-এ মিডিয়া অ্যাসেট এডিট, কনভার্ট ও এক্সপোর্ট করার সুবিধা দেয়। এই পৃষ্ঠা থেকে কীভাবে মূল ট্রান্সফর্মেশন কনফিগার করতে হয় তা জানা যায়:

  • ট্রান্সকোডিং ও ট্রান্সম্যাক্সিং: অডিও ও ভিডিও ফর্ম্যাট কনভার্ট করুন অথবা কন্টেনার স্যাম্পেল কপি করার (ট্রান্সম্যাক্সিং) মাধ্যমে আবার এনকোড করার প্রক্রিয়া এড়িয়ে যান।
  • ট্র্যাক সরানো: মিডিয়া থেকে অডিও বা ভিডিও ট্র্যাক সরিয়ে দিন।
  • ট্রিম করা ও অপ্টিমাইজ করা: টাইমস্ট্যাম্পের মাধ্যমে মিডিয়া ক্লিপ করুন, এর সাথে MP4 এডিট লিস্ট ও ট্রিম অপ্টিমাইজেশন ব্যবহার করে দ্রুত এক্সপোর্ট করার বিকল্প।
  • ভিডিও এফেক্ট: স্কেল, রোটেট করা বা কাস্টম OpenGL শেডার এফেক্ট প্রয়োগ করা, এছাড়াও, ExoPlayer-এ প্রিভিউ করা যায়।
  • ইনপুট হিসেবে ছবি: কাস্টম সময়সীমা ও ফ্রেম রেট সহ স্থির ছবিকে ভিডিও ক্লিপে পরিবর্তন করুন।
  • অডিও প্রসেসিং: কাঁচা অডিও পরিবর্তন করতে AudioProcessor ইনস্ট্যান্সের চেইন।

ফর্ম্যাটের মধ্যে ট্রান্সকোড করা

Transformer তৈরি করার সময় আপনি আউটপুট অডিও ও ভিডিও ফর্ম্যাট নির্দিষ্ট করতে পারবেন। যেমন, নিম্নলিখিত কোড থেকে কীভাবে Transformer-কে H.264/AVC ভিডিও ও AAC অডিও আউটপুট দেওয়ার জন্য কনফিগার করতে হয় তা জানতে পারবেন:

Kotlin

Transformer.Builder(context)
  .setVideoMimeType(MimeTypes.VIDEO_H264)
  .setAudioMimeType(MimeTypes.AUDIO_AAC)
  .build()

জাভা

new Transformer.Builder(context)
    .setVideoMimeType(MimeTypes.VIDEO_H264)
    .setAudioMimeType(MimeTypes.AUDIO_AAC)
    .build();

ইনপুট মিডিয়া ফর্ম্যাট যদি আগে থেকেই অডিও বা ভিডিওর কনফিগারেশনের সাথে ম্যাচ করে, তাহলে Transformer অটোমেটিক ট্রান্সম্যাক্সিং-এ পরিবর্তন করে, অর্থাৎ, ইনপুট কন্টেনার থেকে আউটপুট কন্টেনারে পরিবর্তন না করেই কম্প্রেস করা স্যাম্পেল কপি করে। এটি একই ফর্ম্যাটে ডিকোড ও আবার এনকোড করার জন্য প্রয়োজনীয় কম্পিউটেশনাল খরচ ও সম্ভাব্য কোয়ালিটি কমে যাওয়াকে এড়িয়ে যায়।

অডিও বা ভিডিও সরানো

EditedMediaItem.Builder ব্যবহার করে অডিও বা ভিডিও সরানো, যেমন:

Kotlin

EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()

জাভা

new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();

ক্লিপ ট্রিম করা

ইনপুট মিডিয়া আইটেমে ক্লিপিং কনফিগারেশন সেট করে, নির্দিষ্ট করা শুরু ও শেষের টাইমস্ট্যাম্পের বাইরের যেকোনও মিডিয়া আপনি সরিয়ে দিতে পারবেন। যেমন, ১০ সেকেন্ড থেকে ২০ সেকেন্ডের মধ্যে থাকা মিডিয়া দিয়ে তৈরি ক্লিপ পেতে:

Kotlin

val inputMediaItem =
  MediaItem.Builder()
    .setUri(uri)
    .setClippingConfiguration(
      MediaItem.ClippingConfiguration.Builder()
        .setStartPositionMs(10_000)
        .setEndPositionMs(20_000)
        .build()
    )
    .build()

জাভা

MediaItem inputMediaItem =
    new MediaItem.Builder()
        .setUri(uri)
        .setClippingConfiguration(
            new MediaItem.ClippingConfiguration.Builder()
                .setStartPositionMs(10_000)
                .setEndPositionMs(20_000)
                .build())
        .build();

MP4 এডিট তালিকা

দ্রুত ট্রিম করার জন্য, Transformer MP4 এডিট লিস্টে কাজ করে, এর ফলে সম্পূর্ণ ভিডিও আবার ট্রান্সকোড না করেই আরও দক্ষতার সাথে "শুধুমাত্র ট্রিম" এডিট করা যায়। এই পদ্ধতিতে এডিট লিস্টের মধ্যে আগে থেকে এনকোড করা স্যাম্পেল ও "প্রি-রোল" ব্যবহার করা হয়, যা প্লেয়ারকে নির্দিষ্ট পয়েন্ট থেকে প্লেব্যাক শুরু করার নির্দেশ দেয়। এর ফলে, অবাঞ্ছিত প্রাথমিক সেগমেন্ট এড়িয়ে যাওয়া যায়।

শুধু ট্রিম করার এডিট অনেক দ্রুত করতে, কল করুন experimentalSetMp4EditListTrimEnabled(true)।

Kotlin

Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build()

জাভা

new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
এটি মনে রাখা গুরুত্বপূর্ণ যে সব মিডিয়া প্লেয়ার "প্রি-রোল" পজিশনে কাজ করে না। এর অর্থ হল, এই ধরনের প্লেয়ার ব্যবহার করা হলে, এনকোড করা স্যাম্পেলের একেবারে শুরু থেকে ফাইলটি প্লেব্যাক করা শুরু করবে। এর মধ্যে কোনও এডিট লিস্ট সংক্রান্ত তথ্য থাকলেও, সেটি কোনও আলাদা শুরুর পয়েন্ট নির্দিষ্ট করতে পারে না।

ট্রিম অপ্টিমাইজ করা

ভিডিওর শুরু ট্রিম করার লেটেন্সি কমাতে, ট্রিম অপ্টিমাইজেশন চালু করুন।

Kotlin

Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build()

জাভা

new Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build();

এটি ভিডিওর যতটা সম্ভব কম অংশ ডিকোড ও আবার এনকোড করে এক্সপোর্ট করার প্রসেসকে দ্রুততর করে, তারপর আবার এনকোড করা ডেটা আসল ভিডিওর বাকি অংশের সাথে স্টিচ করে। ইনপুট ফাইলের অংশকে নতুন এনকোড করা আউটপুটের সাথে স্টিচ করতে পারার উপরই অপ্টিমাইজেশন নির্ভর করে। এর অর্থ হল, এনকোডারের আউটপুট ফর্ম্যাট এবং ইনপুট ফর্ম্যাটকে মানানসই হতে হবে। যেমন, ফাইলটি যদি অন্য এনকোডার ইমপ্লিমেন্টেশন সহ কোনও ডিভাইসে তৈরি করা হয়, তাহলে অপ্টিমাইজেশন প্রয়োগ করা সম্ভব নাও হতে পারে। অপ্টিমাইজেশন সফল হতে হলে, Transformer-কে দেওয়া এনকোডারকে EncoderFactory ইনপুট ফর্ম্যাটের সাথে মানানসই লেভেল ও প্রোফাইল থাকতে হবে।

এই অপ্টিমাইজেশন শুধুমাত্র একটি অ্যাসেট সহ MP4 ইনপুটের সাথে কাজ করে, যার মধ্যে কোনও এফেক্ট থাকে না। তবে, এর মধ্যে কোনও অপ ভিডিও এফেক্ট এবং ৯০ ডিগ্রি দ্বারা বিভাজ্য রোটেশন থাকতে পারে। অপ্টিমাইজেশন কাজ না করলে, Transformer অটোমেটিক স্বাভাবিক এক্সপোর্ট প্রসেসে ফিরে যায় এবং ExportResult.OptimizationResult-এ অপ্টিমাইজেশনের ফলাফল রিপোর্ট করে।

আমরা এই কার্যকারিতা যাচাই করছি এবং আশা করছি যে এটি পরবর্তী রিলিজেই পরীক্ষামূলক হিসেবে আর থাকবে না।

ভিডিও এডিট করা

EditedMediaItems ক্রম অনুযায়ী প্রয়োগ করার জন্য অডিও প্রসেসর ও ভিডিও এফেক্টের তালিকা থাকতে হবে। লাইব্রেরিতে সাধারণ ব্যবহারের ক্ষেত্রে ভিডিও এফেক্ট প্রয়োগ করার সুবিধা অন্তর্ভুক্ত থাকে, অথবা আপনি কাস্টম এফেক্ট লিখতে এবং এডিট করা মিডিয়া আইটেম তৈরি করার সময় সেগুলি পাস করতে পারেন।

আপনি মিডিয়া রিস্কেল করতে পারবেন, যা 4k বা 8k ভিডিওর মতো খুব হাই রেজোলিউশন ইনপুট নিয়ে কাজ করার সময় প্রসেসিং রিসোর্স বা ব্যান্ডউইথ সেভ করার জন্য সহায়ক হতে পারে। যেমন, ৪৮০ পিক্সেল উচ্চতায় আনুপাতিকভাবে স্কেল করতে:

Kotlin

EditedMediaItem.Builder(MediaItem.fromUri(uri))
  .setEffects(
    Effects(
      /* audioProcessors= */ listOf(),
      /* videoEffects= */ listOf(Presentation.createForHeight(480)),
    )
  )
  .build()

জাভা

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(Presentation.createForHeight(480))))
    .build();

অথবা, আপনি কোনও নির্দিষ্ট ফ্যাক্টর দিয়ে স্কেল করতে পারেন, যেমন, সাইজ অর্ধেক করতে:

Kotlin

val editedMediaItem =
  EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
      Effects(
        /* audioProcessors= */ listOf(),
        /* videoEffects= */ listOf(
          ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build()
        ),
      )
    )
    .build()

জাভা

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(
                new ScaleAndRotateTransformation.Builder().setScale(.5f, .5f).build())))
    .build();

আপনি একই পদ্ধতিতে রোটেশন কনফিগার করতে পারবেন:

Kotlin

EditedMediaItem.Builder(MediaItem.fromUri(uri))
  .setEffects(
    Effects(
      /* audioProcessors= */ listOf(),
      /* videoEffects= */ listOf(
        ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build()
      ),
    )
  )
  .build()

জাভা

new EditedMediaItem.Builder(MediaItem.fromUri(uri))
    .setEffects(
        new Effects(
            /* audioProcessors= */ ImmutableList.of(),
            /* videoEffects= */ ImmutableList.of(
                new ScaleAndRotateTransformation.Builder().setRotationDegrees(90f).build())))
    .build();

কাস্টম ভিডিও এফেক্ট

প্রয়োগ করার জন্য Effects কনস্ট্রাক্টর অডিও ও ভিডিও এফেক্টের একটি তালিকা গ্রহণ করে। অভ্যন্তরীণভাবে, Transformer-এর এফেক্ট ফ্রেমওয়ার্ক ভিডিও এফেক্টের তালিকা GL শেডার প্রোগ্রামের একটি সিকোয়েন্সে কনভার্ট করে যা ক্রমানুসারে প্রয়োগ করা হয়। কিছু ক্ষেত্রে, এফেক্ট ফ্রেমওয়ার্ক একটি শেডার প্রোগ্রামের মাধ্যমে একাধিক এফেক্ট প্রয়োগ করতে পারে। যেমন, একটি শেডার প্রোগ্রাম একাধিক পরপর ম্যাট্রিক্স ট্রান্সফর্মেশন প্রয়োগ করতে পারে, যা দক্ষতা ও কোয়ালিটি উন্নত করে।

ExoPlayer-এ প্রিভিউ করার জন্য ভিডিও এফেক্টও কাজ করে, এর জন্য ExoPlayer.setVideoEffects ব্যবহার করা হয়। এই API কীভাবে ব্যবহার করতে হয় তার উদাহরণ দেখতে, এফেক্ট ডেমো অ্যাপ দেখুন।

ডেমো অ্যাপে কাস্টম ভিডিও এফেক্টের উদাহরণ দেওয়া আছে।

ইনপুট ছবি

Transformer, ছবি ইনপুট হিসেবে গ্রহণ করে এবং সেগুলিকে স্ট্যাটিক ভিডিও ক্লিপ হিসেবে বিবেচনা করে। ইনপুট সোর্স হিসেবে কোনও ছবি কনফিগার করতে, এইসব ধাপ ফলো করুন:

  • MediaItem.Builder ব্যবহার করে MediaItem তৈরি করুন। setImageDurationMs কল করে আউটপুট ভিডিওতে ছবির ডিসপ্লে সময়সীমা নির্দিষ্ট করুন।

  • MediaItem-কে মোড়ক হিসেবে ব্যবহার করে EditedMediaItem তৈরি করো। জেনারেট করা ভিডিও স্ট্রিমের জন্য টার্গেট ফ্রেম রেট নির্দিষ্ট করতে EditedMediaItem.Builder#setFrameRate ব্যবহার করুন।

নিচের উদাহরণে দেখানো হয়েছে যে কীভাবে ৩০ ফ্রেম প্রতি সেকেন্ডে ৫-সেকেন্ডের ভিডিও তৈরি করতে একটি ছবি ইনপুট কনফিগার করতে হয়:

Kotlin

val imageMediaItem =
  MediaItem.Builder()
    .setUri(imageUri)
    .setImageDurationMs(5000) // 5 seconds
    .build()

val editedImageItem =
  EditedMediaItem.Builder(imageMediaItem)
    .setFrameRate(30) // 30 frames per second
    .build()

জাভা

MediaItem imageMediaItem =
    new MediaItem.Builder()
        .setUri(imageUri)
        .setImageDurationMs(5000) // 5 seconds
        .build();
new EditedMediaItem.Builder(imageMediaItem)
    .setFrameRate(30) // 30 frames per second
    .build();

অডিও এডিট

কাঁচা (PCM) অডিওতে AudioProcessor ইনস্ট্যান্সের একটি ক্রম প্রয়োগ করে অডিও এফেক্ট প্রয়োগ করা হয়। ExoPlayer, অডিও এডিট প্রিভিউ করার অনুমতি দিয়ে DefaultAudioSink.Builder-এ অডিও প্রসেসর পাস করার সুবিধা দেয়।