首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用Xamarin.MP4Transcoder.Transcoder将视频转码为自定义分辨率

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

Stack Overflow用户
提问于 2017-05-12 18:09:59
回答 1查看 1.1K关注 0票数 1

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

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

代码语言:javascript
复制
MediaFormat obj = MediaFormat.CreateVideoFormat("video/mp4", 480, 640);


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

代码语言:javascript
复制
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

任何帮助都是非常感谢的。提前感谢!!

EN

回答 1

Stack Overflow用户

发布于 2017-07-07 20:28:14

我不得不做类似的事情,幸运的是我找到了它是如何在Java语言中实现的,然后我就把它转换成了C#。

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

代码语言:javascript
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43935094

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档