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()
Java
new Transformer.Builder(context) .setVideoMimeType(MimeTypes.VIDEO_H264) .setAudioMimeType(MimeTypes.AUDIO_AAC) .build();
หากรูปแบบสื่ออินพุตตรงกับการกำหนดค่าสำหรับเสียง หรือวิดีโออยู่แล้ว Transformer จะเปลี่ยนไปใช้ การแปลงมัลติเพล็กซ์ โดยอัตโนมัติ ซึ่งเป็นการคัดลอก ตัวอย่างที่บีบอัดจากคอนเทนเนอร์อินพุตไปยังคอนเทนเนอร์เอาต์พุตโดยไม่มี การแก้ไข วิธีนี้จะช่วยหลีกเลี่ยงค่าใช้จ่ายในการคำนวณและการสูญเสียคุณภาพที่อาจเกิดขึ้นจากการถอดรหัสและเข้ารหัสใหม่ในรูปแบบเดียวกัน
นำเสียงหรือวิดีโอออก
นำเสียงหรือวิดีโอออกโดยใช้ EditedMediaItem.Builder เช่น
Kotlin
EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build()
Java
new EditedMediaItem.Builder(inputMediaItem).setRemoveAudio(true).build();
ตัดคลิป
คุณสามารถนำสื่อใดๆ ที่อยู่นอกการประทับเวลาเริ่มต้นและสิ้นสุดที่ระบุออกได้โดยการตั้งค่าการตัดในรายการสื่ออินพุต ตัวอย่างเช่น หากต้องการสร้างคลิปที่มีเฉพาะสื่อระหว่าง 10 วินาทีถึง 20 วินาที ให้ทำดังนี้
Kotlin
val inputMediaItem = MediaItem.Builder() .setUri(uri) .setClippingConfiguration( MediaItem.ClippingConfiguration.Builder() .setStartPositionMs(10_000) .setEndPositionMs(20_000) .build() ) .build()
Java
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()
Java
new Transformer.Builder(context).experimentalSetMp4EditListTrimEnabled(true).build();
การเพิ่มประสิทธิภาพการตัด
หากต้องการลดเวลาในการตอบสนองของการตัดวิดีโอส่วนต้น ให้เปิดใช้การเพิ่มประสิทธิภาพการตัด
Kotlin
Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build()
Java
new Transformer.Builder(context).experimentalSetTrimOptimizationEnabled(true).build();
วิธีนี้จะช่วยเร่งการส่งออกโดยการถอดรหัสและเข้ารหัสวิดีโอใหม่ให้น้อยที่สุด แล้วนำข้อมูลที่เข้ารหัสใหม่มาต่อกับวิดีโอต้นฉบับส่วนที่เหลือ การเพิ่มประสิทธิภาพนี้ขึ้นอยู่กับความสามารถในการนำไฟล์อินพุตบางส่วนมาต่อกับเอาต์พุตที่เข้ารหัสใหม่ ซึ่งหมายความว่ารูปแบบเอาต์พุตของตัวเข้ารหัสและรูปแบบอินพุตต้องเข้ากันได้ ดังนั้น หากไฟล์ถูกสร้างขึ้นในอุปกรณ์ที่มีการใช้งานตัวเข้ารหัสที่แตกต่างกัน ก็เป็นไปได้ว่าคุณจะใช้การเพิ่มประสิทธิภาพไม่ได้
การเพิ่มประสิทธิภาพจะสำเร็จได้ก็ต่อเมื่อตัวเข้ารหัสที่ให้ไว้กับ Transformer ผ่าน EncoderFactory มีระดับและโปรไฟล์ที่เข้ากันได้กับรูปแบบอินพุต
การเพิ่มประสิทธิภาพนี้ใช้ได้กับอินพุต MP4 แบบชิ้นงานเดียวที่ไม่มีเอฟเฟกต์ใดๆ ยกเว้นเอฟเฟกต์วิดีโอแบบไม่มีการดำเนินการและเอฟเฟกต์การหมุนที่หารด้วย 90 องศาลงตัว หากการเพิ่มประสิทธิภาพล้มเหลว Transformer จะกลับไปใช้การส่งออกปกติโดยอัตโนมัติ และรายงานผลลัพธ์ของการเพิ่มประสิทธิภาพใน ExportResult.OptimizationResult
เรากำลังตรวจสอบฟังก์ชันการทำงานนี้และคาดว่าจะไม่ใช่ฟังก์ชันการทำงานแบบทดลองในรุ่นต่อๆ ไป
การแก้ไขวิดีโอ
EditedMediaItems มีรายการโปรเซสเซอร์เสียงและเอฟเฟกต์วิดีโอที่จะใช้ตามลำดับ ไลบรารีมีการใช้งานเอฟเฟกต์วิดีโอสำหรับกรณีการใช้งานทั่วไป หรือคุณจะเขียนเอฟเฟกต์ที่กำหนดเองและส่งผ่านเมื่อสร้างรายการสื่อที่แก้ไขก็ได้
คุณสามารถปรับขนาดสื่อได้ ซึ่งจะเป็นประโยชน์ในการประหยัดทรัพยากรการประมวลผลหรือแบนด์วิดท์เมื่อต้องจัดการกับอินพุตที่มีความละเอียดสูงมาก เช่น วิดีโอ 4K หรือ 8K ตัวอย่างเช่น หากต้องการปรับขนาดตามสัดส่วนให้มีความสูง 480 พิกเซล ให้ทำดังนี้
Kotlin
EditedMediaItem.Builder(MediaItem.fromUri(uri)) .setEffects( Effects( /* audioProcessors= */ listOf(), /* videoEffects= */ listOf(Presentation.createForHeight(480)), ) ) .build()
Java
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()
Java
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()
Java
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โดยใช้MediaItem.Builderระบุระยะเวลาการแสดงรูปภาพในวิดีโอเอาต์พุตโดยเรียกใช้setImageDurationMsสร้าง
EditedMediaItemที่ครอบMediaItemระบุอัตราเฟรมเป้าหมายสำหรับสตรีมวิดีโอที่สร้างขึ้นโดยใช้EditedMediaItem.Builder#setFrameRate
ตัวอย่างต่อไปนี้แสดงวิธีกำหนดค่าอินพุตรูปภาพเพื่อสร้างวิดีโอ 5 วินาทีที่ 30 เฟรมต่อวินาที
Kotlin
val imageMediaItem = MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build() val editedImageItem = EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build()
Java
MediaItem imageMediaItem = new MediaItem.Builder() .setUri(imageUri) .setImageDurationMs(5000) // 5 seconds .build(); new EditedMediaItem.Builder(imageMediaItem) .setFrameRate(30) // 30 frames per second .build();
การแก้ไขเสียง
เอฟเฟกต์เสียงจะใช้งานโดยการใช้ลำดับอินสแตนซ์ AudioProcessor กับเสียงดิบ (PCM) ExoPlayer รองรับการส่งโปรเซสเซอร์เสียงไปยัง DefaultAudioSink.Builder ซึ่งช่วยให้ดูตัวอย่างการแก้ไขเสียงได้