001package net.bramp.ffmpeg.info; 002 003import com.google.common.base.Splitter; 004import java.io.BufferedReader; 005import java.io.IOException; 006import java.util.ArrayList; 007import java.util.Collections; 008import java.util.HashMap; 009import java.util.List; 010import java.util.Map; 011 012/** Parses FFmpeg informational output such as codecs, formats, and channel layouts. */ 013public final class InfoParser { 014 private InfoParser() { 015 throw new AssertionError("No instances for you!"); 016 } 017 018 /** Parses channel layout information from ffmpeg output. */ 019 public static List<ChannelLayout> parseLayouts(BufferedReader r) throws IOException { 020 Map<String, IndividualChannel> individualChannelLookup = new HashMap<>(); 021 List<ChannelLayout> channelLayouts = new ArrayList<>(); 022 023 String line; 024 boolean parsingIndividualChannels = false; 025 boolean parsingChannelLayouts = false; 026 027 while ((line = r.readLine()) != null) { 028 if (line.startsWith("NAME") || line.isEmpty()) { 029 // Skip header and empty lines 030 } else if (line.equals("Individual channels:")) { 031 parsingIndividualChannels = true; 032 parsingChannelLayouts = false; 033 } else if (line.equals("Standard channel layouts:")) { 034 parsingIndividualChannels = false; 035 parsingChannelLayouts = true; 036 } else if (parsingIndividualChannels) { 037 String[] s = line.split(" ", 2); 038 IndividualChannel individualChannel = new IndividualChannel(s[0], s[1].trim()); 039 channelLayouts.add(individualChannel); 040 individualChannelLookup.put(individualChannel.getName(), individualChannel); 041 } else if (parsingChannelLayouts) { 042 String[] s = line.split(" ", 2); 043 List<IndividualChannel> decomposition = new ArrayList<>(); 044 for (String channelName : Splitter.on('+').split(s[1].trim())) { 045 decomposition.add(individualChannelLookup.get(channelName)); 046 } 047 048 channelLayouts.add( 049 new StandardChannelLayout(s[0], Collections.unmodifiableList(decomposition))); 050 } 051 } 052 053 return channelLayouts; 054 } 055}