Android Open Source - M3UPlayer M3 U Parser






From Project

Back to project page M3UPlayer.

License

The source code is released under:

Apache License

If you think the Android project M3UPlayer listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package com.iptv.parser;
/* w  w w .ja v a 2  s. c om*/
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * This class is used to parse a .m3u file.
 * 
 * @author Ke
 */
public class M3UParser {
  private static final String PREFIX_EXTM3U = "#EXTM3U";
  private static final String PREFIX_EXTINF = "#EXTINF:";
  private static final String PREFIX_COMMENT = "#";
  private static final String EMPTY_STRING = "";
  private static final String ATTR_NAME = "name";
  private static final String ATTR_TYPE = "type";
  private static final String ATTR_DLNA_EXTRAS = "dlna_extras";
  private static final String ATTR_PLUGIN = "plugin";
  private static final String ATTR_CHANNEL_NAME = "channel_name";
  private static final String ATTR_DURATION = "duration";
  private static final String ATTR_LOGO = "logo";
  private static final String ATTR_GROUP_TITLE = "group-title";
  private static final String ATTR_TVG_PREFIX = "tvg-";
  private static final String ATTR_TVG_SUFFIX = "-tvg";
  private static final String INVALID_STREAM_URL = "http://0.0.0.0:1234";

  private static M3UParser mInstance = null;
  private M3UHandler mHandler = null;
  private M3UItem mTempItem = null;

  private M3UParser() {
  }

  public static final M3UParser getInstance() {
    if (mInstance == null) {
      mInstance = new M3UParser();
    }
    return mInstance;
  }

  /**
   * Setup a default handler to handle the m3u file parse result.
   * 
   * @param handler
   *            a M3UHandler instance.
   */
  public void setHandler(M3UHandler handler) {
    mHandler = handler;
  }

  /**
   * Use the default handler to parse a m3u file.
   * 
   * @param filename
   *            a file to be parsed.
   */
  public void parse(String filename) {
    parse(filename, mHandler);
  }

  /**
   * Use a specific handler to parse a m3u file.
   * 
   * @param filename
   *            a file to be parsed.
   * @param handler
   *            a specific handler which will not change the default handler.
   */
  public void parse(String filename, M3UHandler handler) {
    if (handler == null) { // No need do anything, if no handler.
      return;
    }
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(
          new FileInputStream(filename)));
      String tmp = null;
      while ((tmp = shrink(br.readLine())) != null) {
        if (tmp.startsWith(PREFIX_EXTM3U)) {
          handler.onReadEXTM3U(parseHead(shrink(tmp.replaceFirst(
              PREFIX_EXTM3U, EMPTY_STRING))));
        } else if (tmp.startsWith(PREFIX_EXTINF)) {
          // The old item must be committed when we meet a new item.
          flush(handler);
          mTempItem = parseItem(shrink(tmp.replaceFirst(
              PREFIX_EXTINF, EMPTY_STRING)));
        } else if (tmp.startsWith(PREFIX_COMMENT)) {
          // Do nothing.
        } else if (tmp.equals(EMPTY_STRING)) {
          // Do nothing.
        } else { // The single line is treated as the stream URL.
          updateURL(tmp);
        }
      }
      flush(handler);
      br.close();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  private String shrink(String str) {
    return str == null ? null : str.trim();
  }

  private void flush(M3UHandler handler) {
    if (mTempItem != null) {
      // The invalid item must be skipped.
      if (mTempItem.getStreamURL() != null) {
        handler.onReadEXTINF(mTempItem);
      }
      mTempItem = null;
    }
  }

  private void updateURL(String url) {
    if (mTempItem != null && !INVALID_STREAM_URL.equals(url)) {
      mTempItem.setStreamURL(url.trim().split("\\s*")[0]);
    }
  }

  private void putAttr(Map<String, String> map, String key, String value) {
    map.put(key, value);
  }

  private String getAttr(Map<String, String> map, String key) {
    String value = map.get(key);
    if (value == null) {
      value = map.get(ATTR_TVG_PREFIX + key);
      if (value == null) {
        value = map.get(key + ATTR_TVG_SUFFIX);
      }
    }
    return value;
  }

  private M3UHead parseHead(String words) {
    Map<String, String> attr = parseAttributes(words);
    M3UHead header = new M3UHead();
    header.setName(getAttr(attr, ATTR_NAME));
    header.setType(getAttr(attr, ATTR_TYPE));
    header.setDLNAExtras(getAttr(attr, ATTR_DLNA_EXTRAS));
    header.setPlugin(getAttr(attr, ATTR_PLUGIN));
    return header;
  }

  private M3UItem parseItem(String words) {
    Map<String, String> attr = parseAttributes(words);
    M3UItem item = new M3UItem();
    item.setChannelName(getAttr(attr, ATTR_CHANNEL_NAME));
    item.setDuration(convert2int(getAttr(attr, ATTR_DURATION)));
    item.setLogoURL(getAttr(attr, ATTR_LOGO));
    item.setGroupTitle(getAttr(attr, ATTR_GROUP_TITLE));
    item.setType(getAttr(attr, ATTR_TYPE));
    item.setDLNAExtras(getAttr(attr, ATTR_DLNA_EXTRAS));
    item.setPlugin(getAttr(attr, ATTR_PLUGIN));
    return item;
  }

  private Map<String, String> parseAttributes(String words) {
    Map<String, String> attr = new HashMap<String, String>();
    if (words == null || words.equals(EMPTY_STRING)) {
      return attr;
    }
    Status status = Status.READY;
    String tmp = words;
    StringBuffer connector = new StringBuffer();
    int i = 0;
    char c = tmp.charAt(i);
    if (c == '-' || Character.isDigit(c)) {
      connector.append(c);
      while (++i < tmp.length()) {
        c = tmp.charAt(i);
        if (Character.isDigit(c)) {
          connector.append(c);
        } else {
          break;
        }
      }
      putAttr(attr, ATTR_DURATION, connector.toString());
      tmp = shrink(tmp.replaceFirst(connector.toString(), EMPTY_STRING));
      reset(connector);
      i = 0;
    }
    String key = EMPTY_STRING;
    boolean startWithQuota = false;
    while (i < tmp.length()) {
      c = tmp.charAt(i++);
      switch (status) {
      case READY:
        if (Character.isWhitespace(c)) {
          // Do nothing
        } else if (c == ',') {
          putAttr(attr, ATTR_CHANNEL_NAME, tmp.substring(i));
          i = tmp.length();
        } else {
          connector.append(c);
          status = Status.READING_KEY;
        }
        break;
      case READING_KEY:
        if (c == '=') {
          key = shrink(key + connector.toString());
          reset(connector);
          status = Status.KEY_READY;
        } else {
          connector.append(c);
        }
        break;
      case KEY_READY:
        if (!Character.isWhitespace(c)) {
          if (c == '"') {
            startWithQuota = true;
          } else {
            connector.append(c);
          }
          status = Status.READING_VALUE;
        }
        break;
      case READING_VALUE:
        if (startWithQuota) {
          connector.append(c);
          int end = tmp.indexOf("\"", i);
          end = end == -1 ? tmp.length() : end;
          connector.append(tmp.substring(i, end));
          startWithQuota = false;
          putAttr(attr, key, connector.toString());
          i = end + 1;
          reset(connector);
          key = EMPTY_STRING;
          status = Status.READY;
          break;
        }
        if (Character.isWhitespace(c)) {
          if (connector.length() > 0) {
            putAttr(attr, key, connector.toString());
            reset(connector);
          }
          key = EMPTY_STRING;
          status = Status.READY;
        } else {
          connector.append(c);
        }
        break;
      default:
        break;
      }
    }
    if (!key.equals(EMPTY_STRING) && connector.length() > 0) {
      putAttr(attr, key, connector.toString());
      reset(connector);
    }
    return attr;
  }

  private int convert2int(String value) {
    int ret = -1;
    try {
      ret = Integer.parseInt(value);
    } catch (Exception e) {
      ret = -1;
    }
    return ret;
  }

  private void reset(StringBuffer buffer) {
    buffer.delete(0, buffer.length());
  }

  private static enum Status {
    READY, READING_KEY, KEY_READY, READING_VALUE,
  }
}




Java Source Code List

com.iptv.parser.M3UFile.java
com.iptv.parser.M3UHandler.java
com.iptv.parser.M3UHead.java
com.iptv.parser.M3UItem.java
com.iptv.parser.M3UParser.java
com.iptv.parser.M3UToolSet.java
com.iptv.parser.package-info.java
com.iptv.player.Player.java
com.iptv.utils.BaseActivity.java
com.iptv.utils.FileBrowser.java
com.iptv.utils.Interlude.java
com.iptv.utils.MessageBox.java
com.iptv.utils.SystemProperties.java