Example #1
0
  /**
   * Request the next track from the trackmanager and play it. When a 404 is returned, delete this
   * show. On any other error: log it and try again in 0.5s.
   */
  private void play_next_track() {
    try {
      last_action = "get next track";
      current_track = new JSONObject(get_url(pop_url));
      WMSLoggerFactory.getLogger(null).info(current_path() + " on " + id);
      boolean success = stream.play("mp3:" + current_path(), 0, -1, true);
      pop_error = false;
      last_action = "play " + current_path();
      if (!success) {
        last_action = "failed play " + current_path();
        schedule_play_next_track();
      }

    } catch (Callback404Exception e) {
      last_action = "remove show";
      Shows.remove_show(app.getName(), id);
      return;
    } catch (IOException e) { // streamer offline?
      WMSLoggerFactory.getLogger(null)
          .error("streamer unreachable (IOException in get_url) in " + id);
      WMSLoggerFactory.getLogger(null).error("asdf", e);
      pop_error = true;
      wait(500);
      schedule_play_next_track();
    } catch (Exception e) {
      WMSLoggerFactory.getLogger(null).error("Unexpected exception in " + id, e);
      pop_error = true;
      wait(500);
      schedule_play_next_track();
    }
  }
Example #2
0
  /**
   * Get the body of the given url.
   *
   * @param url
   * @return
   * @throws IOException when the connection fails or dies
   * @throws Callback404Exception when 404 is returned by the other side.
   */
  public String get_url(String url) throws IOException, Callback404Exception {
    URL u = new URL(url);
    HttpURLConnection uc = (HttpURLConnection) u.openConnection();
    uc.setConnectTimeout(5000);
    uc.setReadTimeout(5000);
    WMSLoggerFactory.getLogger(null).debug("get url: >" + url + "<");

    if (uc.getResponseCode() == 404) {
      WMSLoggerFactory.getLogger(null).info("404 returned");
      throw new Callback404Exception(id);
    }

    return slurp(uc.getInputStream());
  }
Example #3
0
 /** Delete the file we're currently playing if delete_after_play == true */
 private void maybe_delete_current_track() {
   try {
     if (current_track.getBoolean("delete_after_play?")) {
       boolean b = new File(current_absolute_path()).delete();
       last_action += " -> delete";
       if (!b) WMSLoggerFactory.getLogger(null).error("Delete file returned false " + id);
       else WMSLoggerFactory.getLogger(null).info("Deleted file " + current_absolute_path());
     }
   } catch (JSONException e) {
     WMSLoggerFactory.getLogger(null).error("Json exception " + id, e);
     /* delete_after_play not found, so we don't delete.
     if current_track was the reason for the fail, the track would not have been played. */
   } catch (Exception e) {
     /* Just making sure streams don't die by unknown errors */
     WMSLoggerFactory.getLogger(null).error("Unexpected exception in " + id, e);
   }
 }
Example #4
0
public class Show implements IStreamActionNotify {
  private static final WMSLogger logger = WMSLoggerFactory.getLogger(Show.class);
  private Stream stream = null;
  private String pop_url = null;
  private String id = null;
  private IApplication app = null;
  /**
   * there might still be callbacks scheduled after closing the stream We can check this var to stop
   * the loop.
   */
  private boolean closed = false;

  public boolean pop_error = false;
  public String last_action = "";
  private JSONObject current_track = null;
  private static ThreadPool pop_track_thread_pool = null;

  /**
   * Create underlying stream and queue the first play_next_track.
   *
   * @param id Name of the stream.
   * @param pop_url The url to request the next track from.
   */
  Show(IApplication app, String id, String pop_url) {
    stream = Stream.createInstance(app.getVHost(), app.getName(), id);
    stream.setRepeat(false);
    stream.addListener(this);
    this.pop_url = pop_url;
    this.id = id;
    this.app = app;
    schedule_play_next_track();
  }

  /* Schedule play_next_track in the threadpool of the server,
   * so it won't block the thread on errors or on creation.
   */
  private void schedule_play_next_track() {
    if (closed) return;

    pop_track_thread_pool.execute(
        new Runnable() {
          @Override
          public void run() {
            play_next_track();
          }
        });
  }

  /**
   * Request the next track from the trackmanager and play it. When a 404 is returned, delete this
   * show. On any other error: log it and try again in 0.5s.
   */
  private void play_next_track() {
    try {
      last_action = "get next track";
      current_track = new JSONObject(get_url(pop_url));
      WMSLoggerFactory.getLogger(null).info(current_path() + " on " + id);
      boolean success = stream.play("mp3:" + current_path(), 0, -1, true);
      pop_error = false;
      last_action = "play " + current_path();
      if (!success) {
        last_action = "failed play " + current_path();
        schedule_play_next_track();
      }

    } catch (Callback404Exception e) {
      last_action = "remove show";
      Shows.remove_show(app.getName(), id);
      return;
    } catch (IOException e) { // streamer offline?
      WMSLoggerFactory.getLogger(null)
          .error("streamer unreachable (IOException in get_url) in " + id);
      WMSLoggerFactory.getLogger(null).error("asdf", e);
      pop_error = true;
      wait(500);
      schedule_play_next_track();
    } catch (Exception e) {
      WMSLoggerFactory.getLogger(null).error("Unexpected exception in " + id, e);
      pop_error = true;
      wait(500);
      schedule_play_next_track();
    }
  }

  /** Delete the file we're currently playing if delete_after_play == true */
  private void maybe_delete_current_track() {
    try {
      if (current_track.getBoolean("delete_after_play?")) {
        boolean b = new File(current_absolute_path()).delete();
        last_action += " -> delete";
        if (!b) WMSLoggerFactory.getLogger(null).error("Delete file returned false " + id);
        else WMSLoggerFactory.getLogger(null).info("Deleted file " + current_absolute_path());
      }
    } catch (JSONException e) {
      WMSLoggerFactory.getLogger(null).error("Json exception " + id, e);
      /* delete_after_play not found, so we don't delete.
      if current_track was the reason for the fail, the track would not have been played. */
    } catch (Exception e) {
      /* Just making sure streams don't die by unknown errors */
      WMSLoggerFactory.getLogger(null).error("Unexpected exception in " + id, e);
    }
  }

  private String current_absolute_path() throws JSONException {
    return this.app.getAppInstance("_definst_").getStreamStoragePath() + '/' + current_path();
  }

  private String current_path() throws JSONException {
    return "" + current_track.getString("bucket") + '/' + current_track.getString("filename");
  }

  /**
   * Thread.sleep, but just returns when InterruptedException is thrown.
   *
   * @param ms
   */
  private static void wait(int ms) {
    try {
      Thread.sleep(ms);
    } catch (InterruptedException e1) {
    }
  }

  //	private String s3bucket() {
  //		return Server.getInstance().getProperties().getPropertyStr("s3bucket");
  //	}

  public void onPlaylistItemStop(Stream stream, PlaylistItem item) {
    WMSLoggerFactory.getLogger(null)
        .info("Track finished: " + item.getName() + "on Stream: " + stream.getName());
    maybe_delete_current_track();
    play_next_track();
  }

  public void onPlaylistItemStart(Stream stream, PlaylistItem item) {
    WMSLoggerFactory.getLogger(null)
        .info("Item Started: " + item.getName() + "on Stream: " + stream.getName());
    send_stream_title();
  }

  private void send_stream_title() {
    AMFDataMixedArray data = new AMFDataMixedArray();
    try {
      String stream_title = current_track.getString("stream_title");
      byte[] title2 = stream_title.getBytes(java.nio.charset.Charset.defaultCharset().name());
      data.put("StreamTitle", new AMFDataItem(new String(title2, "UTF-8")));
      stream.getPublisher().getStream().send("onMetaData", data);
    } catch (java.io.UnsupportedEncodingException e) {
    } catch (JSONException e) {
    }
  }

  /**
   * Get the body of the given url.
   *
   * @param url
   * @return
   * @throws IOException when the connection fails or dies
   * @throws Callback404Exception when 404 is returned by the other side.
   */
  public String get_url(String url) throws IOException, Callback404Exception {
    URL u = new URL(url);
    HttpURLConnection uc = (HttpURLConnection) u.openConnection();
    uc.setConnectTimeout(5000);
    uc.setReadTimeout(5000);
    WMSLoggerFactory.getLogger(null).debug("get url: >" + url + "<");

    if (uc.getResponseCode() == 404) {
      WMSLoggerFactory.getLogger(null).info("404 returned");
      throw new Callback404Exception(id);
    }

    return slurp(uc.getInputStream());
  }

  private String slurp(java.io.InputStream istream) throws IOException {
    String ret = "";
    BufferedReader in = new BufferedReader(new InputStreamReader(istream));
    String inputLine;

    while ((inputLine = in.readLine()) != null) ret += inputLine;
    in.close();
    return ret;
  }

  public class Callback404Exception extends java.lang.Exception {
    private static final long serialVersionUID = 1L;

    Callback404Exception(String msg) {
      super(msg);
    }
  }

  public void close() {
    closed = true;
    stream.removeListener(this);
    stream.getPublisher().unpublish();
    stream.close();

    stream = null;
    app = null;
  }

  {
    pop_track_thread_pool = new ThreadPool(null, "pop_retry");
    pop_track_thread_pool.init(5);
  }
}
Example #5
0
 public void onPlaylistItemStart(Stream stream, PlaylistItem item) {
   WMSLoggerFactory.getLogger(null)
       .info("Item Started: " + item.getName() + "on Stream: " + stream.getName());
   send_stream_title();
 }
Example #6
0
 public void onPlaylistItemStop(Stream stream, PlaylistItem item) {
   WMSLoggerFactory.getLogger(null)
       .info("Track finished: " + item.getName() + "on Stream: " + stream.getName());
   maybe_delete_current_track();
   play_next_track();
 }