FFmpegUtil { static MediaInfo parseMediaInfo(File mediaFile, String mediaDetailsJsonStr) { long durationMs = 0; Integer totalBitrateK = null; MediaContainer container = null; VideoCodec videoCodec = null; String videoResolution = null; Integer videoBitrateK = null; String videoFramerate = null; AudioCodec audioCodec = null; Integer audioSampleRate = null; Integer audioBitrateK = null; int audioChannels = 2; ObjectMapper mapper = new ObjectMapper(); try { JsonNode root = mapper.readTree(mediaDetailsJsonStr); if(root != null) { JsonNode format = root.get("format"); if(format != null) { JsonNode duration = format.get("duration"); if(duration != null) { durationMs = (int)(duration.asDouble() * 1000); } JsonNode bitrate = format.get("bit_rate"); if(bitrate != null) { totalBitrateK = bitrate.asInt()/1000; } JsonNode formatName = format.get("format_name"); if(formatName != null) { String formatNameStr = formatName.asText(); for(MediaContainer item : MediaContainer.values()) { if(formatNameStr.contains(item.ffmpegName)) { container = item; break; } } } } JsonNode streams = root.get("streams"); if(streams != null) { for (int index = 0; index < streams.size(); index++) { JsonNode stream = streams.get(index); JsonNode codecType = stream.get("codec_type"); if (codecType == null) { continue; } if (codecType.asText().equals("video")) { JsonNode codecName = stream.get("codec_name"); if (codecName == null) { continue; } videoCodec = VideoCodec.fromName(codecName.asText()); JsonNode width = stream.get("width"); JsonNode height = stream.get("height"); if (width == null || height == null) { continue; } videoResolution = width + "x" + height; JsonNode bitrate = stream.get("bit_rate"); if (bitrate != null) { videoBitrateK = bitrate.asInt() / 1000; } JsonNode frameRate = stream.get("avg_frame_rate"); if (frameRate == null) { continue; } try { String frameRateStr = frameRate.asText(); String[] frameRateSplit = frameRateStr.split("/"); int frameRateNum = Integer.parseInt(frameRateSplit[0]); int frameRateDem = 1; if (frameRateSplit.length > 1) { frameRateDem = Integer.parseInt(frameRateSplit[1]); } double frameRateValue = frameRateNum / (double) frameRateDem; videoFramerate = String.format(Locale.US, "%.2f", frameRateValue); if (videoFramerate.contains(".00")) { videoFramerate = videoFramerate.replace(".00", ""); } } catch (NumberFormatException e) { continue; } } if (codecType.asText().equals("audio")) { JsonNode codecName = stream.get("codec_name"); if (codecName == null) { continue; } audioCodec = AudioCodec.fromName(codecName.asText()); JsonNode sampleRate = stream.get("sample_rate"); if (sampleRate == null) { continue; } audioSampleRate = sampleRate.asInt(); JsonNode bitrate = stream.get("bit_rate"); if (bitrate != null) { audioBitrateK = bitrate.asInt() / 1000; } JsonNode channelLaoyout = stream.get("channel_layout"); if (channelLaoyout == null) { continue; } audioChannels = channelLaoyout.asText().equals("mono") ? 1 : 2; } } } } } catch (IOException e) { Log.w(TAG, "Failed to read media details for file : " + mediaFile.getAbsolutePath() + "\n" + mediaDetailsJsonStr, e); } if(totalBitrateK != null) { if(videoBitrateK == null) { if(audioBitrateK != null) { videoBitrateK = totalBitrateK - audioBitrateK; } if(videoBitrateK == null) { videoBitrateK = totalBitrateK - 100; } } } MediaInfo info = null; if(container != null && (videoCodec != null || audioCodec != null)) { info = new MediaInfo(mediaFile, durationMs, container, videoCodec, videoResolution, videoBitrateK, videoFramerate, audioCodec, audioSampleRate, audioBitrateK, audioChannels); } return info; }  static boolean init(final Context context); static void call(final String[] command, @NonNull final ExecuteBinaryResponseHandler handler); static void probe(final String[] command, @NonNull final ExecuteBinaryResponseHandler handler); static void callGetOutput(@NonNull final String [] command,
                                     @NonNull final ResultCallbackHandler<String> resultHandler); static void probeGetOutput(@NonNull final String [] command,
                                      @NonNull final ResultCallbackHandler<String> resultHandler); static void cancelCall(); static boolean isFFmpegRunning(); static Long timestampToMs(String timestamp); static void getMediaDetails(final File mediaFile, final ResultCallbackHandler<MediaInfo> resultHandler); static void getSupportedContainers(final ResultCallbackHandler<List<MediaContainer>> resultHandler);  }
@Test public void parseMediaInfo() throws Exception { File file = new File("/dev/null"); String string = "{\n" + " \"streams\": [\n" + " {\n" + " \"index\": 0,\n" + " \"codec_name\": \"mp3\",\n" + " \"codec_long_name\": \"MP3 (MPEG audio layer 3)\",\n" + " \"codec_type\": \"audio\",\n" + " \"codec_time_base\": \"1/44100\",\n" + " \"codec_tag_string\": \"[0][0][0][0]\",\n" + " \"codec_tag\": \"0x0000\",\n" + " \"sample_fmt\": \"s16p\",\n" + " \"sample_rate\": \"44100\",\n" + " \"channels\": 2,\n" + " \"channel_layout\": \"stereo\",\n" + " \"bits_per_sample\": 0,\n" + " \"r_frame_rate\": \"0/0\",\n" + " \"avg_frame_rate\": \"0/0\",\n" + " \"time_base\": \"1/14112000\",\n" + " \"start_pts\": 353600,\n" + " \"start_time\": \"0.025057\",\n" + " \"duration_ts\": 63109324800,\n" + " \"duration\": \"4472.032653\",\n" + " \"bit_rate\": \"128000\",\n" + " \"disposition\": {\n" + " \"default\": 0,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " },\n" + " \"tags\": {\n" + " \"encoder\": \"Lavc57.48\"\n" + " }\n" + " }\n" + " ],\n" + " \"format\": {\n" + " \"filename\": \"/Users/test/Downloads/recording.mp3\",\n" + " \"nb_streams\": 1,\n" + " \"nb_programs\": 0,\n" + " \"format_name\": \"mp3\",\n" + " \"format_long_name\": \"MP2/3 (MPEG audio layer 2/3)\",\n" + " \"start_time\": \"0.025057\",\n" + " \"duration\": \"4472.032653\",\n" + " \"size\": \"71553077\",\n" + " \"bit_rate\": \"128000\",\n" + " \"probe_score\": 51,\n" + " \"tags\": {\n" + " \"major_brand\": \"dash\",\n" + " \"minor_version\": \"0\",\n" + " \"compatible_brands\": \"iso6mp41\",\n" + " \"encoder\": \"Lavf57.41.100\"\n" + " }\n" + " }\n" + "}"; MediaInfo info = FFmpegUtil.parseMediaInfo(file, string); assertEquals(file, info.file); assertEquals( 4472032, info.durationMs); assertEquals(MediaContainer.MP3, info.container); assertEquals(null, info.videoCodec); assertEquals(null, info.videoResolution); assertEquals(Integer.valueOf(0), info.videoBitrateK); assertEquals(null, info.videoFramerate); assertEquals(AudioCodec.MP3, info.audioCodec); assertEquals(Integer.valueOf(44100), info.audioSampleRate); assertEquals(Integer.valueOf(128), info.audioBitrateK); assertEquals(Integer.valueOf(2), info.audioChannels); string = "{\n" + " \"streams\": [\n" + " {\n" + " \"index\": 0,\n" + " \"codec_name\": \"h264\",\n" + " \"codec_long_name\": \"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10\",\n" + " \"profile\": \"Constrained Baseline\",\n" + " \"codec_type\": \"video\",\n" + " \"codec_time_base\": \"12864731/489240000\",\n" + " \"codec_tag_string\": \"avc1\",\n" + " \"codec_tag\": \"0x31637661\",\n" + " \"width\": 1080,\n" + " \"height\": 1920,\n" + " \"coded_width\": 1080,\n" + " \"coded_height\": 1920,\n" + " \"has_b_frames\": 0,\n" + " \"sample_aspect_ratio\": \"1:1\",\n" + " \"display_aspect_ratio\": \"9:16\",\n" + " \"pix_fmt\": \"yuv420p\",\n" + " \"level\": 40,\n" + " \"color_range\": \"tv\",\n" + " \"color_space\": \"bt709\",\n" + " \"color_transfer\": \"bt709\",\n" + " \"color_primaries\": \"bt709\",\n" + " \"chroma_location\": \"left\",\n" + " \"refs\": 1,\n" + " \"is_avc\": \"true\",\n" + " \"nal_length_size\": \"4\",\n" + " \"r_frame_rate\": \"180000/2\",\n" + " \"avg_frame_rate\": \"244620000/12864731\",\n" + " \"time_base\": \"1/90000\",\n" + " \"start_pts\": 0,\n" + " \"start_time\": \"0.000000\",\n" + " \"duration_ts\": 12864731,\n" + " \"duration\": \"142.941456\",\n" + " \"bit_rate\": \"4499166\",\n" + " \"bits_per_raw_sample\": \"8\",\n" + " \"nb_frames\": \"2718\",\n" + " \"disposition\": {\n" + " \"default\": 1,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " },\n" + " \"tags\": {\n" + " \"creation_time\": \"2018-01-02 00:09:32\",\n" + " \"language\": \"eng\",\n" + " \"handler_name\": \"VideoHandle\"\n" + " }\n" + " },\n" + " {\n" + " \"index\": 1,\n" + " \"codec_name\": \"aac\",\n" + " \"codec_long_name\": \"AAC (Advanced Audio Coding)\",\n" + " \"profile\": \"LC\",\n" + " \"codec_type\": \"audio\",\n" + " \"codec_time_base\": \"1/22050\",\n" + " \"codec_tag_string\": \"mp4a\",\n" + " \"codec_tag\": \"0x6134706d\",\n" + " \"sample_fmt\": \"fltp\",\n" + " \"sample_rate\": \"22050\",\n" + " \"channels\": 1,\n" + " \"channel_layout\": \"mono\",\n" + " \"bits_per_sample\": 0,\n" + " \"r_frame_rate\": \"0/0\",\n" + " \"avg_frame_rate\": \"0/0\",\n" + " \"time_base\": \"1/44100\",\n" + " \"start_pts\": 0,\n" + " \"start_time\": \"0.000000\",\n" + " \"duration_ts\": 6286221,\n" + " \"duration\": \"142.544694\",\n" + " \"bit_rate\": \"63860\",\n" + " \"nb_frames\": \"3064\",\n" + " \"disposition\": {\n" + " \"default\": 1,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " },\n" + " \"tags\": {\n" + " \"creation_time\": \"2018-01-02 00:09:32\",\n" + " \"language\": \"eng\",\n" + " \"handler_name\": \"SoundHandle\"\n" + " }\n" + " }\n" + " ],\n" + " \"format\": {\n" + " \"filename\": \"/Users/test/Downloads/ScreenRecord-2018-01-01-19-07-10.mp4\",\n" + " \"nb_streams\": 2,\n" + " \"nb_programs\": 0,\n" + " \"format_name\": \"mov,mp4,m4a,3gp,3g2,mj2\",\n" + " \"format_long_name\": \"QuickTime / MOV\",\n" + " \"start_time\": \"0.000000\",\n" + " \"duration\": \"142.862000\",\n" + " \"size\": \"81603639\",\n" + " \"bit_rate\": \"4569648\",\n" + " \"probe_score\": 100,\n" + " \"tags\": {\n" + " \"major_brand\": \"mp42\",\n" + " \"minor_version\": \"0\",\n" + " \"compatible_brands\": \"isommp42\",\n" + " \"creation_time\": \"2018-01-02 00:09:32\",\n" + " \"com.android.version\": \"7.1.2\"\n" + " }\n" + " }\n" + "}\n"; info = FFmpegUtil.parseMediaInfo(file, string); assertEquals(file, info.file); assertEquals( 142862, info.durationMs); assertEquals(MediaContainer.MP4, info.container); assertEquals(VideoCodec.H264, info.videoCodec); assertEquals("1080x1920", info.videoResolution); assertEquals(Integer.valueOf(4499), info.videoBitrateK); assertEquals("19.01", info.videoFramerate); assertEquals(AudioCodec.AAC, info.audioCodec); assertEquals(Integer.valueOf(22050), info.audioSampleRate); assertEquals(Integer.valueOf(63), info.audioBitrateK); assertEquals(Integer.valueOf(1), info.audioChannels); string = "{\n" + " \"streams\": [\n" + " {\n" + " \"index\": 0,\n" + " \"codec_name\": \"h264\",\n" + " \"codec_long_name\": \"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10\",\n" + " \"profile\": \"Main\",\n" + " \"codec_type\": \"video\",\n" + " \"codec_time_base\": \"1/50\",\n" + " \"codec_tag_string\": \"[0][0][0][0]\",\n" + " \"codec_tag\": \"0x0000\",\n" + " \"width\": 640,\n" + " \"height\": 360,\n" + " \"coded_width\": 640,\n" + " \"coded_height\": 360,\n" + " \"has_b_frames\": 0,\n" + " \"sample_aspect_ratio\": \"1:1\",\n" + " \"display_aspect_ratio\": \"16:9\",\n" + " \"pix_fmt\": \"yuv420p\",\n" + " \"level\": 30,\n" + " \"chroma_location\": \"left\",\n" + " \"refs\": 1,\n" + " \"is_avc\": \"true\",\n" + " \"nal_length_size\": \"4\",\n" + " \"r_frame_rate\": \"25/1\",\n" + " \"avg_frame_rate\": \"25/1\",\n" + " \"time_base\": \"1/1000\",\n" + " \"start_pts\": 0,\n" + " \"start_time\": \"0.000000\",\n" + " \"bits_per_raw_sample\": \"8\",\n" + " \"disposition\": {\n" + " \"default\": 0,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " }\n" + " },\n" + " {\n" + " \"index\": 1,\n" + " \"codec_name\": \"aac\",\n" + " \"codec_long_name\": \"AAC (Advanced Audio Coding)\",\n" + " \"profile\": \"LC\",\n" + " \"codec_type\": \"audio\",\n" + " \"codec_time_base\": \"1/44100\",\n" + " \"codec_tag_string\": \"[0][0][0][0]\",\n" + " \"codec_tag\": \"0x0000\",\n" + " \"sample_fmt\": \"fltp\",\n" + " \"sample_rate\": \"48000\",\n" + " \"channels\": 6,\n" + " \"channel_layout\": \"5.1\",\n" + " \"bits_per_sample\": 0,\n" + " \"r_frame_rate\": \"0/0\",\n" + " \"avg_frame_rate\": \"0/0\",\n" + " \"time_base\": \"1/1000\",\n" + " \"start_pts\": 3,\n" + " \"start_time\": \"0.003000\",\n" + " \"disposition\": {\n" + " \"default\": 0,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " }\n" + " }\n" + " ],\n" + " \"format\": {\n" + " \"filename\": \"/Users/test/Downloads/big_buck_bunny_360p_1mb.flv\",\n" + " \"nb_streams\": 2,\n" + " \"nb_programs\": 0,\n" + " \"format_name\": \"flv\",\n" + " \"format_long_name\": \"FLV (Flash Video)\",\n" + " \"start_time\": \"0.000000\",\n" + " \"duration\": \"6.893000\",\n" + " \"size\": \"1048720\",\n" + " \"bit_rate\": \"1217142\",\n" + " \"probe_score\": 100,\n" + " \"tags\": {\n" + " \"encoder\": \"Lavf53.24.2\"\n" + " }\n" + " }\n" + "}"; info = FFmpegUtil.parseMediaInfo(file, string); assertEquals(file, info.file); assertEquals( 6893, info.durationMs); assertEquals(MediaContainer.FLV, info.container); assertEquals(VideoCodec.H264, info.videoCodec); assertEquals("640x360", info.videoResolution); assertEquals(Integer.valueOf(1117), info.videoBitrateK); assertEquals("25", info.videoFramerate); assertEquals(AudioCodec.AAC, info.audioCodec); assertEquals(Integer.valueOf(48000), info.audioSampleRate); assertEquals(null, info.audioBitrateK); assertEquals(Integer.valueOf(2), info.audioChannels); string = "{\n" + " \"streams\": [\n" + " {\n" + " \"index\": 0,\n" + " \"codec_name\": \"h264\",\n" + " \"codec_long_name\": \"H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10\",\n" + " \"profile\": \"Main\",\n" + " \"codec_type\": \"video\",\n" + " \"codec_time_base\": \"1/50\",\n" + " \"codec_tag_string\": \"[0][0][0][0]\",\n" + " \"codec_tag\": \"0x0000\",\n" + " \"width\": 640,\n" + " \"height\": 360,\n" + " \"coded_width\": 640,\n" + " \"coded_height\": 360,\n" + " \"has_b_frames\": 0,\n" + " \"sample_aspect_ratio\": \"1:1\",\n" + " \"display_aspect_ratio\": \"16:9\",\n" + " \"pix_fmt\": \"yuv420p\",\n" + " \"level\": 30,\n" + " \"chroma_location\": \"left\",\n" + " \"refs\": 1,\n" + " \"is_avc\": \"true\",\n" + " \"nal_length_size\": \"4\",\n" + " \"r_frame_rate\": \"25/1\",\n" + " \"avg_frame_rate\": \"25/1\",\n" + " \"time_base\": \"1/1000\",\n" + " \"start_pts\": 0,\n" + " \"start_time\": \"0.000000\",\n" + " \"bits_per_raw_sample\": \"8\",\n" + " \"disposition\": {\n" + " \"default\": 0,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " }\n" + " },\n" + " {\n" + " \"index\": 1,\n" + " \"codec_name\": \"aac\",\n" + " \"codec_long_name\": \"AAC (Advanced Audio Coding)\",\n" + " \"profile\": \"LC\",\n" + " \"codec_type\": \"audio\",\n" + " \"codec_time_base\": \"1/44100\",\n" + " \"codec_tag_string\": \"[0][0][0][0]\",\n" + " \"codec_tag\": \"0x0000\",\n" + " \"sample_fmt\": \"fltp\",\n" + " \"sample_rate\": \"48000\",\n" + " \"channels\": 6,\n" + " \"channel_layout\": \"5.1\",\n" + " \"bits_per_sample\": 0,\n" + " \"r_frame_rate\": \"0/0\",\n" + " \"avg_frame_rate\": \"0/0\",\n" + " \"time_base\": \"1/1000\",\n" + " \"start_pts\": 3,\n" + " \"start_time\": \"0.003000\",\n" + " \"bit_rate\": 517000,\n" + " \"disposition\": {\n" + " \"default\": 0,\n" + " \"dub\": 0,\n" + " \"original\": 0,\n" + " \"comment\": 0,\n" + " \"lyrics\": 0,\n" + " \"karaoke\": 0,\n" + " \"forced\": 0,\n" + " \"hearing_impaired\": 0,\n" + " \"visual_impaired\": 0,\n" + " \"clean_effects\": 0,\n" + " \"attached_pic\": 0\n" + " }\n" + " }\n" + " ],\n" + " \"format\": {\n" + " \"filename\": \"/Users/test/Downloads/big_buck_bunny_360p_1mb.flv\",\n" + " \"nb_streams\": 2,\n" + " \"nb_programs\": 0,\n" + " \"format_name\": \"flv\",\n" + " \"format_long_name\": \"FLV (Flash Video)\",\n" + " \"start_time\": \"0.000000\",\n" + " \"duration\": \"6.893000\",\n" + " \"size\": \"1048720\",\n" + " \"bit_rate\": \"1217142\",\n" + " \"probe_score\": 100,\n" + " \"tags\": {\n" + " \"encoder\": \"Lavf53.24.2\"\n" + " }\n" + " }\n" + "}"; info = FFmpegUtil.parseMediaInfo(file, string); assertEquals(Integer.valueOf(700), info.videoBitrateK); }