Android设备视频编码MediaFormat支持格式查询及适配方案
Hey there! Let's tackle your two Android media encoding questions—device fragmentation can be a real headache, but we’ve got practical steps to work through it.
To figure out which video encoding formats your device supports, you’ll need to dig into Android’s media codec APIs and verify both broad support and specific parameters:
Fetch the full list of supported encoders
Use theMediaCodecListclass (prefer theREGULAR_CODECSflag in API 21+ to exclude legacy/rare codecs). Iterate through the codec infos, filter for encoders, and check their supported media types:MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); for (MediaCodecInfo codecInfo : codecList.getCodecInfos()) { if (!codecInfo.isEncoder()) continue; for (String type : codecInfo.getSupportedTypes()) { if (type.startsWith("video/")) { // This is a supported video encoding format (e.g., video/avc for H.264) Log.d("CodecSupport", "Supported encoder: " + codecInfo.getName() + " for type: " + type); } } }Verify specific parameter support
Knowing a format is supported isn’t enough—you need to confirm the device handles your required resolution, frame rate, bitrate, and color format. UseMediaCodecInfo.CodecCapabilities:String targetType = "video/avc"; MediaCodecInfo codecInfo = getEncoderForType(targetType); // Implement this helper MediaCodecInfo.CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(targetType); MediaCodecInfo.VideoCapabilities videoCaps = capabilities.getVideoCapabilities(); // Check supported resolutions Range<Integer> widthRange = videoCaps.getSupportedWidths(); Range<Integer> heightRange = videoCaps.getSupportedHeights(); // Check supported frame rates Range<Double> frameRateRange = videoCaps.getSupportedFrameRates(); // Check bitrate range Range<Integer> bitrateRange = capabilities.getBitrateRange();Validate with real-world testing
Some devices report support for a format but fail in practice. Always test by initializing the codec, configuring it with your targetMediaFormat, and feeding a test frame. If you get anIOExceptionorIllegalStateException, the device doesn’t actually support that configuration.
Building a filter library like Instagram/Snapchat means dealing with a ton of device-specific quirks during re-encoding. Here’s how to create a robust, compatible MediaFormat:
Start with the original video’s parameters
Reuse as much as possible from the input video’sMediaFormat—this minimizes compatibility issues and reduces processing overhead. Grab values likeKEY_WIDTH,KEY_HEIGHT,KEY_FRAME_RATE, andKEY_COLOR_FORMAT(if the encoder supports it). Only adjust parameters when necessary.Prioritize universal encoding formats
Stick to widely supported formats first:- H.264 (
video/avc): This is the gold standard for Android compatibility—virtually every device running API 16+ supports it. Use this as your default unless you have a specific reason to use something else. - H.265 (
video/hevc): Offers better compression but has spotty support on older devices (API 21+ for basic support, but varies by manufacturer). Only use this if you’ve verified the device supports it.
- H.264 (
Dynamically adjust critical parameters
- Bitrate: Don’t hardcode values. Calculate a reasonable bitrate based on resolution and frame rate (e.g.,
width * height * frameRate * 0.07), then clamp it to the device’s supported bitrate range fromCodecCapabilities. - Color format: This is one of the biggest pain points. After applying filters (which often output RGBA), you’ll need to convert to a format the encoder accepts. Check
capabilities.getSupportedColorFormats()and prioritize:COLOR_FormatYUV420Flexible(API 21+): The most flexible option, works with most modern devices.COLOR_FormatYUV420PlanarorCOLOR_FormatYUV420SemiPlanar: Fallbacks for older devices.
- Resolution: If the original resolution isn’t supported, find the closest supported resolution (e.g., scale 1080p down to 720p if the device can’t encode 1080p). Use
videoCaps.getClosestSupportedWidth()andgetClosestSupportedHeight()to handle this.
- Bitrate: Don’t hardcode values. Calculate a reasonable bitrate based on resolution and frame rate (e.g.,
Build in fallback and error handling
- Degrade gracefully: If your first-choice
MediaFormatfails to initialize, try a more conservative configuration (lower resolution, lower bitrate, different color format). - Alternative encoders: If H.264 fails, fall back to VP8 (
video/x-vnd.on2.vp8)—it’s supported on most devices and has good compatibility. - Catch exceptions: Wrap codec initialization, configuration, and start calls in try-catch blocks to handle
IOExceptionandIllegalStateException, then trigger your fallback logic.
- Degrade gracefully: If your first-choice
Test across devices
There’s no substitute for real-device testing. Focus on popular manufacturers (Samsung, Xiaomi, Huawei) and a range of API levels (from API 21 up to the latest). Tools like Firebase Test Lab can help you cover more devices without owning them all.
内容的提问来源于stack exchange,提问作者isaac.udy




