【问题标题】:How to transcode a video to custom resolution using Xamarin.MP4Transcoder.Transcoder如何使用 Xamarin.MP4Transcoder.Transcoder 将视频转码为自定义分辨率
【发布时间】:2017-10-11 14:49:47
【问题描述】:

我需要使用 Xamarin.MP4Transcoder.Transcoder 将视频转码为 640*480 分辨率。目前有 2 种可用的分辨率 720pFormat 和 960x540Format。 Transcoder 类中有一个名为Transcoder For (IMediaFormatStrategy strategy) 的方法。

我可以创建具有 MIME 类型、宽度和高度的 MediaFormat 对象 通过下面提到的代码sn-p:

MediaFormat obj = MediaFormat.CreateVideoFormat("video/mp4", 480, 640);


但问题是如何将其分配给 IMediaFormatStrategy 或者是否有其他方法可以实现这一点。

Piece of code for Transcoding a video:

Xamarin.MP4Transcoder.Transcoder.For960x540Format().ConvertAsync(inputFile, outputFile, f =>
				{
				  onProgress?.Invoke((int)(f * (double)100), 100);

				  
				} );

inputFile: Video file which needs to be transcoded.
outputFile: Resultant file generated after transcoding.

更多信息可以参考https://github.com/neurospeech/xamarin-android-ffmpeg

感谢任何帮助。提前致谢!!

【问题讨论】:

    标签: ffmpeg xamarin.android video-processing transcoding android-ffmpeg


    【解决方案1】:

    我不得不做类似的事情,幸运的是找到了它是如何用 Java 制作的,然后我只需要将它转换为 C#。

    生成的类(对于 640x360)如下所示:

    public class For640x360Format : Java.Lang.Object, IMediaFormatStrategy
    {
        public static int AUDIO_BITRATE_AS_IS = -1;
        public static int AUDIO_CHANNELS_AS_IS = -1;
        static String TAG = "640x360FormatStrategy";
        static int LONGER_LENGTH = 640;
        static int SHORTER_LENGTH = 360;
        static int DEFAULT_VIDEO_BITRATE = 8000 * 1000; // From Nexus 4 Camera in 720p
        int mVideoBitrate;
        int mAudioBitrate;
        int mAudioChannels;
    
        public For640x360Format ()
        {
            mVideoBitrate = DEFAULT_VIDEO_BITRATE;
            mAudioBitrate = AUDIO_BITRATE_AS_IS;
            mAudioChannels = AUDIO_CHANNELS_AS_IS;
        }
    
        public For640x360Format (int videoBitrate)
        {
            mVideoBitrate = videoBitrate;
            mAudioBitrate = AUDIO_BITRATE_AS_IS;
            mAudioChannels = AUDIO_CHANNELS_AS_IS;
        }
    
        public For640x360Format (int videoBitrate, int audioBitrate, int audioChannels)
        {
            mVideoBitrate = videoBitrate;
            mAudioBitrate = audioBitrate;
            mAudioChannels = audioChannels;
        }
    
        public MediaFormat CreateAudioOutputFormat (MediaFormat inputFormat)
        {
            if (mAudioBitrate == AUDIO_BITRATE_AS_IS || mAudioChannels == AUDIO_CHANNELS_AS_IS) return null;
    
            // Use original sample rate, as resampling is not supported yet.
            MediaFormat format = MediaFormat.CreateAudioFormat (MediaFormatExtraConstants.MimetypeAudioAac,
                                                                inputFormat.GetInteger (MediaFormat.KeySampleRate),
                                                                mAudioChannels);
            // this is obsolete: MediaCodecInfo.CodecProfileLevel.AACObjectLC, so using MediaCodecProfileType.Aacobjectlc instead
            format.SetInteger (MediaFormat.KeyAacProfile, (int)MediaCodecProfileType.Aacobjectlc); 
            format.SetInteger (MediaFormat.KeyBitRate, mAudioBitrate);
            return format;
        }
    
        public MediaFormat CreateVideoOutputFormat (MediaFormat inputFormat)
        {
            int width = inputFormat.GetInteger (MediaFormat.KeyWidth);
            int height = inputFormat.GetInteger (MediaFormat.KeyHeight);
            int longer, shorter, outWidth, outHeight;
    
            if (width >= height)
            {
                longer = width;
                shorter = height;
                outWidth = LONGER_LENGTH;
                outHeight = SHORTER_LENGTH;
            }
            else
            {
                shorter = width;
                longer = height;
                outWidth = SHORTER_LENGTH;
                outHeight = LONGER_LENGTH;
            }
    
            if (longer * 9 != shorter * 16)
            {
                throw new OutputFormatUnavailableException ("This video is not 16:9, and is not able to transcode. (" + width + "x" + height + ")");
            }
            if (shorter <= SHORTER_LENGTH)
            {
                #if DEBUG
                Console.WriteLine ("This video is less or equal to 720p, pass-through. (" + width + "x" + height + ")");
                #endif
    
                return null;
            }
    
            MediaFormat format = MediaFormat.CreateVideoFormat ("video/avc", outWidth, outHeight);
            format.SetInteger (MediaFormat.KeyBitRate, mVideoBitrate);
            format.SetInteger (MediaFormat.KeyFrameRate, 30);
            format.SetInteger (MediaFormat.KeyIFrameInterval, 3);
            // this is obsolete: MediaCodecInfo.CodecCapabilities.COLORFormatSurface, so using MediaCodecCapabilities.Formatsurface instead
            format.SetInteger (MediaFormat.KeyColorFormat, (int)MediaCodecCapabilities.Formatsurface);
    
            return format;
        }
    }
    

    只需将 LONGER_LENGTH 和 SHORTER_LENGTH 更改为您需要的任何分辨率,显然,为它创建一个新类。 也可以只创建一个包含两种长度的通用类,但我还没有需要它。

    Link to the Java code

    【讨论】:

    • 非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    相关资源
    最近更新 更多