如何使用Xamarin.MP4Transcoder.Transcoder将视频转码为自定义分辨率

时间:2017-05-12 10:09:59

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

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

我可以使用MIME类型,宽度和高度创建MediaFormat对象 通过以下提到的代码片段:

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

感谢任何帮助。在此先感谢!!

1 个答案:

答案 0 :(得分: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