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}