1
4

1 に答える 1

2

私も同様のことをしなければなりませんでしたが、幸運にもそれが 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 を必要な解像度に変更し、明らかに新しいクラスを作成します。おそらく、2 つの長さを取るジェネリック クラスを作成することもできますが、まだその必要はありません。

Java コードへのリンク

于 2017-07-07T12:28:13.547 に答える