Jetpack Media3-এর ট্রান্সফরমার API গুলি মিডিয়া সম্পাদনাকে কার্যকর এবং নির্ভরযোগ্য করে তোলার জন্য ডিজাইন করা হয়েছে। ট্রান্সফরমার বেশ কয়েকটি অপারেশন সমর্থন করে, যার মধ্যে রয়েছে:
- ট্রিমিং, স্কেলিং এবং রোটেটিং এর মাধ্যমে একটি ভিডিও পরিবর্তন করা
- ওভারলে এবং ফিল্টারের মতো প্রভাব যোগ করা
- HDR এবং স্লো-মোশন ভিডিওর মতো বিশেষ ফর্ম্যাট প্রক্রিয়াকরণ
- সম্পাদনা প্রয়োগের পরে একটি মিডিয়া আইটেম রপ্তানি করা হচ্ছে
এই পৃষ্ঠাটি আপনাকে ট্রান্সফরমার দ্বারা আচ্ছাদিত কিছু গুরুত্বপূর্ণ ব্যবহারের ক্ষেত্রে নিয়ে যাবে। আরও বিস্তারিত জানার জন্য আপনি Media3 ট্রান্সফরমার সম্পর্কে আমাদের সম্পূর্ণ নির্দেশিকাগুলি দেখতে পারেন।
শুরু করুন
শুরু করতে, Jetpack Media3 এর ট্রান্সফরমার, ইফেক্ট এবং কমন মডিউলের উপর একটি নির্ভরতা যোগ করুন:
implementation "androidx.media3:media3-transformer:1.8.0" implementation "androidx.media3:media3-effect:1.8.0" implementation "androidx.media3:media3-common:1.8.0"
আপনার পছন্দের লাইব্রেরির সংস্করণটি 1.8.0 দিয়ে প্রতিস্থাপন করতে ভুলবেন না। সর্বশেষ সংস্করণটি দেখতে আপনি রিলিজ নোটগুলি দেখতে পারেন।
গুরুত্বপূর্ণ ক্লাস
| শ্রেণী | উদ্দেশ্য |
|---|---|
Transformer | রূপান্তর শুরু করুন এবং বন্ধ করুন এবং চলমান রূপান্তরের অগ্রগতির আপডেটগুলি পরীক্ষা করুন। |
EditedMediaItem | প্রক্রিয়া করার জন্য একটি মিডিয়া আইটেম এবং এতে প্রয়োগ করার জন্য সম্পাদনাগুলি উপস্থাপন করে। |
Effects | অডিও এবং ভিডিও প্রভাবের একটি সংগ্রহ। |
আউটপুট কনফিগার করুন
Transformer.Builder এর সাহায্যে, আপনি এখন TransformationRequest অবজেক্ট তৈরি না করেই ফাংশন সেট করে videoMimeType এবং audioMimetype ডিরেক্টরি নির্দিষ্ট করতে পারেন।
ফর্ম্যাটের মধ্যে ট্রান্সকোড করুন
নিম্নলিখিত কোডটি দেখায় কিভাবে একটি Transformer অবজেক্টকে H.265/AVC ভিডিও এবং AAC অডিও আউটপুট করার জন্য কনফিগার করতে হয়:
কোটলিন
val transformer = Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build()
জাভা
Transformer transformer = new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H265) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
যদি ইনপুট মিডিয়া ফর্ম্যাটটি ইতিমধ্যেই অডিও বা ভিডিওর জন্য রূপান্তর অনুরোধের সাথে মিলে যায়, তাহলে ট্রান্সফরমার স্বয়ংক্রিয়ভাবে ট্রান্সমাক্সিং -এ স্যুইচ করে, অর্থাৎ, সংকুচিত নমুনাগুলিকে ইনপুট কন্টেইনার থেকে আউটপুট কন্টেইনারে পরিবর্তন ছাড়াই অনুলিপি করে। এটি একই ফর্ম্যাটে ডিকোডিং এবং পুনঃএনকোডিংয়ের গণনামূলক খরচ এবং সম্ভাব্য মানের ক্ষতি এড়ায়।
HDR মোড সেট করুন
যদি ইনপুট মিডিয়া ফাইলটি HDR ফর্ম্যাটে থাকে, তাহলে ট্রান্সফরমার কীভাবে HDR তথ্য প্রক্রিয়া করে তার জন্য আপনি কয়েকটি ভিন্ন মোডের মধ্যে একটি বেছে নিতে পারেন। আপনি সম্ভবত HDR_MODE_KEEP_HDR অথবা HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL ব্যবহার করতে চাইবেন।
HDR_MODE_KEEP_HDR | HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL | |
|---|---|---|
| বিবরণ | HDR ডেটা সংরক্ষণ করুন, অর্থাৎ HDR আউটপুট ফর্ম্যাট HDR ইনপুট ফর্ম্যাটের মতোই। | OpenGL টোন-ম্যাপার ব্যবহার করে SDR-তে টোনম্যাপ HDR ইনপুট, যার অর্থ আউটপুট ফর্ম্যাটটি SDR-তে হবে। |
| সমর্থন | FEATURE_HdrEditing ক্ষমতা সহ একটি এনকোডার অন্তর্ভুক্ত ডিভাইসগুলির জন্য API স্তর 31+ এ সমর্থিত। | API লেভেল 29+ এ সমর্থিত। |
| ত্রুটি | যদি সমর্থিত না হয়, তাহলে HDR_MODE_TONE_MAP_HDR_TO_SDR_USING_OPEN_GL ব্যবহার করার চেষ্টা করা হবে। | যদি সমর্থিত না হয়, তাহলে একটি ExportException ছুঁড়ে দেয়। |
যেসব ডিভাইসে প্রয়োজনীয় এনকোডিং ক্ষমতা রয়েছে এবং অ্যান্ড্রয়েড ১৩ (এপিআই লেভেল ৩৩) বা তার বেশি চালিত হয়, সেখানে Transformer অবজেক্ট আপনাকে এইচডিআর ভিডিও সম্পাদনা করতে দেয়। Composition অবজেক্ট তৈরি করার সময় HDR_MODE_KEEP_HDR হল ডিফল্ট মোড, যেমনটি নিম্নলিখিত কোডে দেখানো হয়েছে:
কোটলিন
val composition = Composition.Builder( ImmutableList.of(videoSequence)) .setHdrMode(HDR_MODE_KEEP_HDR) .build()
জাভা
Composition composition = new Composition.Builder( ImmutableList.of(videoSequence)) .setHdrMode(Composition.HDR_MODE_KEEP_HDR) .build();
একটি মিডিয়া আইটেম প্রস্তুত করুন
একটি MediaItem আপনার অ্যাপের একটি অডিও বা ভিডিও আইটেম উপস্থাপন করে। একটি EditedMediaItem একটি MediaItem সংগ্রহ করে এবং এর সাথে রূপান্তরগুলি প্রয়োগ করে।
ভিডিও ট্রিম করুন
ভিডিওর অবাঞ্ছিত অংশগুলি সরাতে, আপনি MediaItem এ একটি ClippingConfiguration যোগ করে কাস্টম শুরু এবং শেষ অবস্থান সেট করতে পারেন।
কোটলিন
val clippingConfiguration = MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) // start at 10 seconds .setEndPositionMs(20_000) // end at 20 seconds .build() val mediaItem = MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration(clippingConfiguration) .build()
জাভা
ClippingConfiguration clippingConfiguration = new MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) // start at 10 seconds .setEndPositionMs(20_000) // end at 20 seconds .build(); MediaItem mediaItem = new MediaItem.Builder() .setUri(videoUri) .setClippingConfiguration(clippingConfiguration) .build();
বিল্ট-ইন এফেক্ট ব্যবহার করুন
Media3-তে সাধারণ রূপান্তরের জন্য বেশ কিছু অন্তর্নির্মিত ভিডিও প্রভাব রয়েছে, উদাহরণস্বরূপ:
| শ্রেণী | প্রভাব |
|---|---|
Presentation | রেজোলিউশন বা আকৃতির অনুপাত অনুসারে মিডিয়া আইটেমটি স্কেল করুন |
ScaleAndRotateTransformation | একটি গুণক দ্বারা মিডিয়া আইটেম স্কেল করুন এবং/অথবা মিডিয়া আইটেমটি ঘোরান |
Crop | মিডিয়া আইটেমটি ছোট বা বড় ফ্রেমে কাটুন |
OverlayEffect | মিডিয়া আইটেমের উপরে একটি টেক্সট বা ছবির ওভারলে যোগ করুন |
অডিও ইফেক্টের জন্য, আপনি AudioProcessor ইনস্ট্যান্সের একটি ক্রম যোগ করতে পারেন যা কাঁচা (PCM) অডিও ডেটা রূপান্তর করবে। উদাহরণস্বরূপ, আপনি অডিও চ্যানেলগুলিকে মিশ্রিত এবং স্কেল করতে একটি ChannelMixingAudioProcessor ব্যবহার করতে পারেন।
এই প্রভাবগুলি ব্যবহার করার জন্য, প্রভাব বা অডিও প্রসেসরের একটি উদাহরণ তৈরি করুন, মিডিয়া আইটেমে আপনি যে অডিও এবং ভিডিও প্রভাবগুলি প্রয়োগ করতে চান তা দিয়ে Effects একটি উদাহরণ তৈরি করুন, তারপর Effects অবজেক্টটি একটি EditedMediaItem এ যুক্ত করুন।
কোটলিন
val channelMixingProcessor = ChannelMixingAudioProcessor() val rotateEffect = ScaleAndRotateTransformation.Builder().setRotationDegrees(60f).build() val cropEffect = Crop(-0.5f, 0.5f, -0.5f, 0.5f) val effects = Effects(listOf(channelMixingProcessor), listOf(rotateEffect, cropEffect)) val editedMediaItem = EditedMediaItem.Builder(mediaItem) .setEffects(effects) .build()
জাভা
ChannelMixingAudioProcessor channelMixingProcessor = new ChannelMixingAudioProcessor(); ScaleAndRotateTransformation rotateEffect = new ScaleAndRotateTransformation.Builder() .setRotationDegrees(60f) .build(); Crop cropEffect = new Crop(-0.5f, 0.5f, -0.5f, 0.5f); Effects effects = new Effects( ImmutableList.of(channelMixingProcessor), ImmutableList.of(rotateEffect, cropEffect) ); EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(mediaItem) .setEffects(effects) .build();
কাস্টম প্রভাব তৈরি করুন
Media3-তে অন্তর্ভুক্ত প্রভাবগুলি প্রসারিত করে, আপনি আপনার ব্যবহারের ক্ষেত্রে নির্দিষ্ট কাস্টম প্রভাব তৈরি করতে পারেন। নিম্নলিখিত উদাহরণে, প্লেব্যাকের প্রথম সেকেন্ডে ফ্রেমটি পূরণ করার জন্য ভিডিওটিকে জুম করতে সাবক্লাস MatrixTransformation ব্যবহার করুন:
কোটলিন
val zoomEffect = MatrixTransformation { presentationTimeUs -> val transformationMatrix = Matrix() // Set the scaling factor based on the playback position val scale = min(1f, presentationTimeUs / 1_000f) transformationMatrix.postScale(/* x */ scale, /* y */ scale) transformationMatrix } val editedMediaItem = EditedMediaItem.Builder(inputMediaItem) .setEffects(Effects(listOf(), listOf(zoomEffect)) .build()
জাভা
MatrixTransformation zoomEffect = presentationTimeUs -> { Matrix transformationMatrix = new Matrix(); // Set the scaling factor based on the playback position float scale = min(1f, presentationTimeUs / 1_000f); transformationMatrix.postScale(/* x */ scale, /* y */ scale); return transformationMatrix; }; EditedMediaItem editedMediaItem = new EditedMediaItem.Builder(inputMediaItem) .setEffects(new Effects(ImmutableList.of(), ImmutableList.of(zoomEffect))) .build();
কোনও ইফেক্টের আচরণ আরও কাস্টমাইজ করার জন্য, একটি GlShaderProgram প্রয়োগ করুন। ইনপুট ফ্রেম প্রক্রিয়া করার জন্য queueInputFrame() পদ্ধতি ব্যবহার করা হয়। উদাহরণস্বরূপ, MediaPipe এর মেশিন লার্নিং ক্ষমতা ব্যবহার করার জন্য, আপনি প্রতিটি ফ্রেমকে MediaPipe গ্রাফের মাধ্যমে পাঠাতে MediaPipe FrameProcessor ব্যবহার করতে পারেন। Transformer ডেমো অ্যাপে এর একটি উদাহরণ দেখুন।
প্রিভিউ এফেক্টস
ExoPlayer এর সাহায্যে, আপনি রপ্তানি প্রক্রিয়া শুরু করার আগে একটি মিডিয়া আইটেমে যোগ করা প্রভাবগুলির পূর্বরূপ দেখতে পারেন। EditedMediaItem এর মতো একই Effects অবজেক্ট ব্যবহার করে, আপনার ExoPlayer ইনস্ট্যান্সে setVideoEffects() কল করুন।
কোটলিন
val player = ExoPlayer.builder(context) .build() .also { exoPlayer -> exoPlayer.setMediaItem(inputMediaItem) exoPlayer.setVideoEffects(effects) exoPlayer.prepare() }
জাভা
ExoPlayer player = new ExoPlayer.builder(context).build(); player.setMediaItem(inputMediaItem); player.setVideoEffects(effects); exoPlayer.prepare();
আপনি ExoPlayer দিয়ে অডিও এফেক্টের প্রিভিউও দেখতে পারেন। আপনার ExoPlayer ইনস্ট্যান্স তৈরি করার সময়, একটি কাস্টম RenderersFactory পাস করুন যা প্লেয়ারের অডিও রেন্ডারারগুলিকে আপনার AudioProcessor সিকোয়েন্স ব্যবহার করে এমন একটি AudioSink এ অডিও আউটপুট করার জন্য কনফিগার করে। নীচের উদাহরণে, আমরা DefaultRenderersFactory এর buildAudioSink() পদ্ধতিকে ওভাররাইড করে এটি করি।
কোটলিন
val player = ExoPlayer.Builder(context, object : DefaultRenderersFactory(context) { override fun buildAudioSink( context: Context, enableFloatOutput: Boolean, enableAudioTrackPlaybackParams: Boolean, enableOffload: Boolean ): AudioSink? { return DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode(if (enableOffload) { DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED } else { DefaultAudioSink.OFFLOAD_MODE_DISABLED }) .setAudioProcessors(arrayOf(channelMixingProcessor)) .build() } }).build()
জাভা
ExoPlayer player = new ExoPlayer.Builder(context, new DefaultRenderersFactory(context) { @Nullable @Override protected AudioSink buildAudioSink( Context context, boolean enableFloatOutput, boolean enableAudioTrackPlaybackParams, boolean enableOffload ) { return new DefaultAudioSink.Builder(context) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) .setOffloadMode( enableOffload ? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED : DefaultAudioSink.OFFLOAD_MODE_DISABLED) .setAudioProcessors(new AudioProcessor[]{channelMixingProcessor}) .build(); } }).build();
একটি রূপান্তর শুরু করুন
অবশেষে, আপনার সম্পাদনাগুলি প্রয়োগ করার জন্য একটি Transformer তৈরি করুন এবং ফলাফল প্রাপ্ত মিডিয়া আইটেমটি রপ্তানি শুরু করুন।
কোটলিন
val transformer = Transformer.Builder(context) .addListener(listener) .build() transformer.start(editedMediaItem, outputPath)
জাভা
Transformer transformer = new Transformer.Builder(context) .addListener(listener) .build(); transformer.start(editedMediaItem, outputPath);
প্রয়োজনে আপনি Transformer.cancel() ব্যবহার করে একইভাবে রপ্তানি প্রক্রিয়া বাতিল করতে পারেন।
অগ্রগতির আপডেটগুলি পরীক্ষা করুন
Transformer.start তাৎক্ষণিকভাবে ফিরে আসে এবং অ্যাসিঙ্ক্রোনাসভাবে চলে। একটি রূপান্তরের বর্তমান অগ্রগতি জিজ্ঞাসা করতে, Transformer.getProgress() কল করুন। এই পদ্ধতিটি একটি ProgressHolder নেয়, এবং যদি অগ্রগতি অবস্থা উপলব্ধ থাকে, অর্থাৎ, যদি পদ্ধতিটি PROGRESS_STATE_AVAILABLE ফেরত দেয়, তাহলে প্রদত্ত ProgressHolder বর্তমান অগ্রগতি শতাংশের সাথে আপডেট করা হবে।
আপনি আপনার Transformer সাথে একজন শ্রোতাও সংযুক্ত করতে পারেন যাতে আপনি সম্পূর্ণতা বা ত্রুটির ঘটনা সম্পর্কে অবহিত হতে পারেন।