Exemplo n.º 1
0
static event_t *
be_gmeplayer_play(const char *url0, media_pipe_t *mp, 
		  char *errbuf, size_t errlen, int hold)
{
  event_t *e;
  char *url, *p;
  int track;
  void *fh;

  url0 += strlen("gmeplayer:");

  url = mystrdupa(url0);
  p = strrchr(url, '/');
  if(p == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return NULL;
  }

  *p++= 0;
  track = atoi(p) - 1;

  if((fh = fa_open(url, errbuf, errlen)) == NULL)
    return NULL;

  e = fa_gme_playfile_internal(mp, fh, errbuf, errlen, hold, track);
  fa_close(fh);
  return e;

}
Exemplo n.º 2
0
static event_t *
be_gmeplayer_play(const char *url0, media_pipe_t *mp, 
		  char *errbuf, size_t errlen, int hold,
		  const char *mimetype)
{
  event_t *e;
  char *url, *p;
  int track;

  url0 += strlen("gmeplayer:");

  url = mystrdupa(url0);
  p = strrchr(url, '/');
  if(p == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return NULL;
  }

  *p++= 0;
  track = atoi(p) - 1;
  buf_t *b;
  if((b = fa_load(url, NULL, errbuf, errlen, NULL, 0, NULL, NULL)) == NULL)
    return NULL;

  e = fa_gme_playfile_internal(mp, b->b_ptr, b->b_size,
			       errbuf, errlen, hold, track, url0);
  buf_release(b);
  return e;
}
Exemplo n.º 3
0
static int
rtmp_probe(const char *url0, char *errbuf, size_t errlen, int timeout_ms)
{
  RTMP *r;
  char *url = mystrdupa(url0);

  r = RTMP_Alloc();
  RTMP_Init(r, NULL);

  if(!RTMP_SetupURL(r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  if(!RTMP_Connect(r, NULL, errbuf, errlen, timeout_ms)) {
    RTMP_Close(r);
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  RTMP_SetReadTimeout(r, timeout_ms);

  if(!RTMP_ConnectStream(r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    RTMP_Close(r);
    RTMP_Free(r);
    return BACKEND_PROBE_FAIL;
  }

  RTMP_Close(r);
  RTMP_Free(r);

  return BACKEND_PROBE_OK;
}
Exemplo n.º 4
0
void
metadata_filename_to_title(const char *filename, int *yearp, rstr_t **titlep)
{
  int year = 0;

  char *s = mystrdupa(filename);

  url_deescape(s);

  int i = strlen(s);

  while(i > 0) {
    
    if(i > 5 && s[i-5] == '.' &&
       isnum(s[i-4]) && isnum(s[i-3]) && isnum(s[i-2]) && isnum(s[i-1])) {
      year = atoi(s + i - 4);
      i -= 5;
      s[i] = 0;
      continue;
    }

    if(i > 7 && s[i-7] == ' ' && s[i-6] == '(' && 
       isnum(s[i-5]) && isnum(s[i-4]) && isnum(s[i-3]) && isnum(s[i-2]) &&
       s[i-1] == ')') {
      year = atoi(s + i - 5);
      i -= 7;
      s[i] = 0;
      continue;
    }

    int j;
    for(j = 0; stopstrings[j] != NULL; j++) {
      int len = strlen(stopstrings[j]);
      if(i > len+1 && (s[i-len-1] == '.' || s[i-len-1] == ' ') &&
	 !strncasecmp(s+i-len, stopstrings[j], len) &&
	 (s[i] == '.' || s[i] == ' ' || s[i] == '-' || s[i] == 0)) {
	i -= len+1;
	s[i] = 0;
	break;
      }
    }
    
    if(stopstrings[j] != NULL)
      continue;

    i--;
  }

  for(i = 0; s[i]; i++) {
    if(s[i] == '.') {
      s[i] = ' ';
    }
  }
 
  if(yearp != NULL)
    *yearp = year;

  if(titlep != NULL)
    *titlep = rstr_alloc(s);
}
Exemplo n.º 5
0
static int
es_file_copy(duk_context *ctx)
{
  char *cleanup;
  char path[URL_MAX];
  char errbuf[256];
  es_context_t *ec = es_get(ctx);

  const char *from = duk_to_string(ctx, 0);
  const char *to   = duk_to_string(ctx, 1);

  cleanup = mystrdupa(to);

  fa_sanitize_filename(cleanup);

  snprintf(path, sizeof(path), "%s/copy/%s",
           ec->ec_storage, cleanup);

  TRACE(TRACE_DEBUG, "JS", "Copying file from '%s' to '%s'", from, path);

  if(fa_copy(path, from, errbuf, sizeof(errbuf)))
    duk_error(ctx, DUK_ERR_ERROR, "Copy failed: %s", errbuf);

  duk_push_string(ctx, path);
  return 1;
}
Exemplo n.º 6
0
static void
notifications_update(void *opaque, prop_event_t event, ...)
{
  statusbar_t *sb = opaque;
  prop_t *p, *txt;
  statusbar_entry_t *sbe;
  char *buf;
  rstr_t *msg;
  int i, l;
  va_list ap;
  va_start(ap, event);

  switch(event) {
  case PROP_ADD_CHILD:
    p = va_arg(ap, prop_t *);

    txt = prop_get_by_name(PNVEC("self", "text"), 1,
			   PROP_TAG_NAMED_ROOT, p, "self",
			   NULL);
    if(txt != NULL) {
      msg = prop_get_string(txt);

      if(msg != NULL) {
	buf = mystrdupa(rstr_get(msg));
	l = strlen(buf);
	for(i = 0; i < l; i++)
	  if(buf[i] < ' ')
	    buf[i] = ' ';

	sbe = calloc(1, sizeof(statusbar_entry_t));
	sbe->p = prop_ref_inc(p);
	sbe->id = gtk_statusbar_push(GTK_STATUSBAR(sb->bar), sb->ctxid, buf);
	LIST_INSERT_HEAD(&sb->entries, sbe, link);
	rstr_release(msg);
      }
      prop_ref_dec(txt);
    }
    break;

  case PROP_DEL_CHILD:
    p = va_arg(ap, prop_t *);

    LIST_FOREACH(sbe, &sb->entries, link)
      if(sbe->p == p)
	break;

    if(sbe == NULL)
      break;

    prop_ref_dec(sbe->p);
    gtk_statusbar_remove(GTK_STATUSBAR(sb->bar), sb->ctxid, sbe->id);
    LIST_REMOVE(sbe, link);
    free(sbe);
    break;

  default:
    break;
  }
}
Exemplo n.º 7
0
static pixmap_t *
fa_image_from_video(const char *url0, const image_meta_t *im,
		    char *errbuf, size_t errlen, int *cache_control,
		    cancellable_t *c)
{
  static char *stated_url;
  static fa_stat_t fs;
  time_t stattime = 0;
  time_t mtime = 0;
  pixmap_t *pm = NULL;
  char cacheid[512];
  char *url = mystrdupa(url0);
  char *tim = strchr(url, '#');
  const char *siz;
  *tim++ = 0;
  int secs = atoi(tim);

  hts_mutex_lock(&image_from_video_mutex[0]);
  
  if(strcmp(url, stated_url ?: "")) {
    free(stated_url);
    stated_url = NULL;
    if(fa_stat(url, &fs, errbuf, errlen)) {
      hts_mutex_unlock(&image_from_video_mutex[0]);
      return NULL;
    }
    stated_url = strdup(url);
  }
  stattime = fs.fs_mtime;
  hts_mutex_unlock(&image_from_video_mutex[0]);

  if(im->im_req_width < 100 && im->im_req_height < 100) {
    siz = "min";
  } else if(im->im_req_width < 200 && im->im_req_height < 200) {
    siz = "mid";
  } else {
    siz = "max";
  }

  snprintf(cacheid, sizeof(cacheid), "%s-%s", url0, siz);
  buf_t *b = blobcache_get(cacheid, "videothumb", 0, 0, NULL, &mtime);
  if(b != NULL && mtime == stattime) {
    pm = pixmap_alloc_coded(b->b_ptr, b->b_size, PIXMAP_JPEG);
    buf_release(b);
    return pm;
  }
  buf_release(b);

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  hts_mutex_lock(&image_from_video_mutex[1]);
  pm = fa_image_from_video2(url, im, cacheid, errbuf, errlen,
			    secs, stattime, c);
  hts_mutex_unlock(&image_from_video_mutex[1]);
  return pm;
}
Exemplo n.º 8
0
static pixmap_t *
fa_image_from_video(const char *url0, const image_meta_t *im,
		    char *errbuf, size_t errlen, int *cache_control,
		    fa_load_cb_t *cb, void *opaque)
{
  static char *stated_url;
  static fa_stat_t fs;
  time_t stattime = 0;
  time_t mtime = 0;
  pixmap_t *pm = NULL;
  char cacheid[512];
  void *data;
  size_t datasize;
  char *url = mystrdupa(url0);
  char *tim = strchr(url, '#');

  *tim++ = 0;
  int secs = atoi(tim);

  hts_mutex_lock(&image_from_video_mutex);
  
  if(strcmp(url, stated_url ?: "")) {
    free(stated_url);
    stated_url = NULL;
    if(fa_stat(url, &fs, errbuf, errlen)) {
      hts_mutex_unlock(&image_from_video_mutex);
      return NULL;
    }
    stated_url = strdup(url);
  }
  stattime = fs.fs_mtime;
  hts_mutex_unlock(&image_from_video_mutex);

  snprintf(cacheid, sizeof(cacheid), "%s-%d-%d-3",
	   url0, im->im_req_width, im->im_req_height);

  data = blobcache_get(cacheid, "videothumb", &datasize, 0, 0,
		       NULL, &mtime);
  if(data != NULL && mtime == stattime) {
    pm = pixmap_alloc_coded(data, datasize, PIXMAP_PNG);
    free(data);
    return pm;
  }

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  hts_mutex_lock(&image_from_video_mutex);
  pm = fa_image_from_video2(url, im, cacheid, errbuf, errlen,
			    secs, stattime, cb, opaque);
  hts_mutex_unlock(&image_from_video_mutex);
  return pm;
}
Exemplo n.º 9
0
void
prop_set_from_tuple(GVariant *v, prop_t *parent)
{
  const char *key =
    g_variant_get_string(g_variant_get_child_value(v, 0), NULL);
  GVariant *value = g_variant_get_variant(g_variant_get_child_value(v, 1));

  char *k = mystrdupa(key);
  fixup_title(k);
  prop_set_from_gvariant(value, prop_create(parent, k));
}
Exemplo n.º 10
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       int flags, int priority,
	       char *errbuf, size_t errlen,
	       const char *mimetype)
{
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  prop_set_string(mp->mp_prop_type, "video");

  RTMP_LogSetLevel(RTMP_LOGINFO);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_Connect(r.r, NULL)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }

  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_DEEP);
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  mp_flush(mp, 0);
  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of stream");

  rtmp_free(&r);
  return e;
}
Exemplo n.º 11
0
static int
be_page_open(prop_t *root, const char *url0, int sync)
{
  prop_t *src = prop_create(root, "model");
  prop_t *metadata = prop_create(src, "metadata");
  char *cap = mystrdupa(url0 + strlen("page:"));

  prop_set_string(prop_create(src, "type"), cap);
  cap[0] = toupper((int)cap[0]);
  prop_set_string(prop_create(metadata, "title"), cap);
  return 0;
}
Exemplo n.º 12
0
static int
sidfile_scandir(fa_dir_t *fd, const char *url, char *errbuf, size_t errlen)
{
  void *fh = NULL;
  char *p, *fpath = mystrdupa(url);
  char buf[128];
  char name[32];
  char turl[URL_MAX];
  int tracks, i;
  fa_dir_entry_t *fde;
  rstr_t *album, *artist;
 

  if((p = strrchr(fpath, '/')) == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return -1;
  }

  *p = 0;
  if((fh = fa_open(fpath, errbuf, errlen)) == NULL)
    return -1;

  if(fa_read(fh, buf, 128) != 128) {
    snprintf(errbuf, errlen, "Unable to read file");
    fa_close(fh);
    return -1;
  }

  album = rstr_alloc(utf8_from_bytes((char *)buf + 0x16, 32, NULL));
  artist = rstr_alloc(utf8_from_bytes((char *)buf + 0x36, 32, NULL));

  tracks = buf[0xf];
  for(i = 0; i < tracks; i++) {

    snprintf(name, sizeof(name), "Track %02d", i + 1);
    snprintf(turl, sizeof(turl), "sidplayer:%s/%d", fpath, i + 1);
    fde = fa_dir_add(fd, turl, name, CONTENT_AUDIO);

    fde->fde_probestatus = FDE_PROBE_DEEP;

    fde->fde_metadata = prop_create_root("metadata");
    prop_set_string(prop_create(fde->fde_metadata, "title"), name);
    prop_set_rstring(prop_create(fde->fde_metadata, "album"), album);
    prop_set_rstring(prop_create(fde->fde_metadata, "artist"), artist);
  }

  rstr_release(album);
  rstr_release(artist);

  fa_close(fh);
  return 0;
}
Exemplo n.º 13
0
static int
es_file_dirname(duk_context *ctx)
{
  es_context_t *ec = es_get(ctx);
  const char *filename = mystrdupa(get_filename(ctx, 0, ec, 0));

  char *x = strrchr(filename, '/');
  if(x) {
    *x = 0;
    duk_push_string(ctx, filename);
  }
  return 1;
}
Exemplo n.º 14
0
/**
 * Compiles a regexp matching all paths of existing file:// services.
 * E.g.: "^(path1|path2|path3...)".
 */
static int
fa_create_paths_regex (regex_t *preg) {
  service_t *s;
  int len = 0;
  char *str, *t;
  int errcode;

  hts_mutex_lock(&service_mutex);

  /* First calculate the space needed for the regex. */
  LIST_FOREACH(s, &services, s_link)
    if (!strncmp(s->s_url, "file://", strlen("file://")))
      len += strlen(s->s_url + strlen("file://")) + strlen("/|");

  if (len == 0) {
    /* No file:// services found. We should either flunk out
     * and do nothing here, or act as if this was a feature
     * and provide un-filtered 'locate' output. I really dont know
     * whats best. */
    str = strdup(".*");

  } else {
    str = t = malloc(len + strlen("^()") + 1);

    t += sprintf(str, "^(");

    /* Then construct the regex. */
    LIST_FOREACH(s, &services, s_link)
      if (!strncmp(s->s_url, "file://", strlen("file://")))
	t += sprintf(t, "%s%s|",
		     deregex(mystrdupa(s->s_url + strlen("file://"))),
		     (s->s_url[strlen(s->s_url)-1] == '/' ? "" : "/"));

    *(t-1) = ')';
  }

  hts_mutex_unlock(&service_mutex);

  if ((errcode = regcomp(preg, str, REG_EXTENDED|REG_ICASE|REG_NOSUB))) {
    char buf[64];
    regerror(errcode, preg, buf, sizeof(buf));
    TRACE(TRACE_ERROR, "FA", "Search regex compilation of \"%s\" failed: %s",
	  str, buf);
    free(str);
    return -1;
  }

  free(str);
  return 0;
}
Exemplo n.º 15
0
void
prop_set_from_vardict(GVariant *v, prop_t *parent)
{
  GVariantIter iter;
  GVariant *value;
  gchar *key;

  g_variant_iter_init(&iter, v);
  while(g_variant_iter_loop(&iter, "{sv}", &key, &value)) {
    char *k = mystrdupa(key);
    fixup_title(k);
    prop_set_from_gvariant(value, prop_create(parent, k));
  }
}
Exemplo n.º 16
0
int
metadata_filename_to_episode(const char *s,
			     int *seasonp, int *episodep,
			     rstr_t **titlep)
{
  int i, j;
  int len = strlen(s);
  int season = -1;
  int episode = -1;
  for(i = 0; i < len; i++) {
    if((s[i] == 's' || s[i] == 'S') && isnum(s[i+1]) && isnum(s[i+2])) {
      int o = 3+i;
      if(s[o] == '.')
	o++;
  
      if((s[o] == 'e' || s[o] == 'E') && isnum(s[o+1]) && isnum(s[o+2])) {
	season = atoi(s+i+1);
	episode = atoi(s+o+1);
	break;
      }
    }
  }
  

  if(season == -1 || episode == -1)
    return -1;

  *seasonp = season;
  *episodep = episode;

  char *t = mystrdupa(s);
  url_deescape(t);

  for(j= 0; j < i; j++) {
    if(t[j] == '.') {
      t[j] = ' ';
    }
  }
  t[j] = 0;

  if(titlep != NULL) {
    if(j)
      *titlep = rstr_alloc(t);
    else
      *titlep = NULL;
  }
  return 0;
}
Exemplo n.º 17
0
int
filebundle_load(const char *p, void **ptr, int *len, int *osize)
{
  const struct filebundle_entry *fe;
  const struct filebundle *fb;
  char *path = mystrdupa(p);

  char *x = strchr(path, '/');
  if(x == NULL)
    return ENOTDIR;

  *x++ = 0;
  for(fb = filebundles; fb != NULL; fb = fb->next) {
    if(!strcmp(path, fb->prefix))
      break;
  }
  if(fb == NULL)
    return ENODEV;

  for(fe = fb->entries; fe->filename != NULL; fe++) {
    if(!strcmp(fe->filename, x))
      break;
  }

  if(fe->filename == NULL)
    return ENOENT;

  if(ptr)
    *ptr = (void *)fe->data;
  if(len)
    *len = fe->size;
  if(osize)
    *osize = fe->original_size;

  return 0;
}
Exemplo n.º 18
0
/**
 * Play given track.
 *
 * We only expect this to be called from the playqueue system.
 */
static event_t *
be_sid2player_play(const char *url0, media_pipe_t *mp, 
		   char *errbuf, size_t errlen, int hold,
		   const char *mimetype)
{
  media_queue_t *mq = &mp->mp_audio;
  char *url, *p;
  int sample = 0;
  media_buf_t *mb = NULL;
  event_t *e;
  int subsong;
  int registered_play = 0;

  void *player;
  
  url0 += strlen("sidplayer:");

  url = mystrdupa(url0);
  p = strrchr(url, '/');
  if(p == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return NULL;
  }

  *p++= 0;
  subsong = atoi(p);

  buf_t *b;

  if((b = fa_load(url, NULL, errbuf, errlen, NULL, 0,
		  NULL, NULL)) == NULL)
    return NULL;

  player = sidcxx_load(b->b_ptr, b->b_size, subsong, errbuf, errlen);
  buf_release(b);
  if(player == NULL)
    return NULL;

  mp_set_playstatus_by_hold(mp, hold, NULL);
  mp->mp_audio.mq_stream = 0;
  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_NONE, 0);
  mp_become_primary(mp);

  while(1) {

    if(mb == NULL) {

      mb = media_buf_alloc_unlocked(mp, sizeof(int16_t) * CHUNK_SIZE * 2);
      mb->mb_data_type = MB_AUDIO;
      mb->mb_channels = 2;
      mb->mb_rate = 44100;

      mb->mb_pts = sample * 1000000LL / mb->mb_rate;
      mb->mb_drive_clock = 1;

      if(!registered_play && mb->mb_pts > METADB_AUDIO_PLAY_THRESHOLD) {
	registered_play = 1;
	metadb_register_play(url0, 1, CONTENT_AUDIO);
      }

      sample += CHUNK_SIZE;

      int16_t *samples = mb->mb_data;

      sidcxx_play(player, samples,
		  CHUNK_SIZE * sizeof(int16_t) * mb->mb_channels);

      // Crossmix 25% 

      int i, l, r, L, R;
      for(i = 0; i < CHUNK_SIZE; i++) {
	l = samples[i * 2 + 0];
	r = samples[i * 2 + 1];

	L = 3 * l + r * 2;
	R = 3 * r + l * 2;

	L = L / 4;
	R = R / 4;

	if(L > 32767)
	  L = 32767;
	if(L < -32768)
	  L = -32768;

	if(R > 32767)
	  R = 32767;
	if(R < -32768)
	  R = -32768;

	samples[i * 2 + 0] = L;
	samples[i * 2 + 1] = R;
      }
    }

    if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
      mb = NULL; /* Enqueue succeeded */
      continue;
    }

    if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {
      mp_flush(mp, 0);
      break;

    } else if(event_is_action(e, ACTION_SKIP_BACKWARD) ||
	      event_is_action(e, ACTION_SKIP_FORWARD) ||
	      event_is_action(e, ACTION_STOP)) {
      mp_flush(mp, 0);
      break;
    }
    event_release(e);
  }  

  sidcxx_stop(player);

  return e;
}
Exemplo n.º 19
0
void
metadata_filename_to_title(const char *filename, int *yearp, rstr_t **titlep)
{
  int year = 0;

  //skip the chars between a starting '[' and ']'.
  char* start=NULL;
  if(filename[0]=='[') {
      start = strchr(filename,']');
      if(start != NULL) {
          start++;
          if(start[0]=='.')
              start++;
      }
      if(start>=filename+strlen(filename)) //don't skip if the '[]' includes the whole filename
          start=NULL;
  }

  char *s ;
  
  if(start==NULL)
    s = mystrdupa(filename);
  else
	s = mystrdupa(start);

  url_deescape(s);

  int i = strlen(s);

  while(i > 0) {

    if(i > 5 && s[i-5] == '.' &&
       isnum(s[i-4]) && isnum(s[i-3]) && isnum(s[i-2]) && isnum(s[i-1])) {
      year = atoi(s + i - 4);
      i -= 5;
      s[i] = 0;
      continue;
    }

    if(i > 7 && s[i-7] == ' ' && s[i-6] == '(' &&
       isnum(s[i-5]) && isnum(s[i-4]) && isnum(s[i-3]) && isnum(s[i-2]) &&
       s[i-1] == ')') {
      year = atoi(s + i - 5);
      i -= 7;
      s[i] = 0;
      continue;
    }

    int j;
    for(j = 0; stopstrings[j] != NULL; j++) {
      int len = strlen(stopstrings[j]);
      if(i > len+1 && (s[i-len-1] == '.' || s[i-len-1] == ' ') &&
	 !strncasecmp(s+i-len, stopstrings[j], len) &&
	 (s[i] == '.' || s[i] == ' ' || s[i] == '-' || s[i] == 0)) {
	i -= len+1;
	s[i] = 0;
	break;
      }
    }

    if(stopstrings[j] != NULL)
      continue;

    i--;
  }

  char *lastword = strrchr(s, ' ');
  if(lastword && lastword > s) {
    int y = atoi(lastword + 1);
    if(y > 1900 && y < 2040) {
      year = y;
      *lastword = 0;
    }
  }




  for(i = 0; s[i]; i++) {
    if(s[i] == '.') {
      s[i] = ' ';
    }
  }

  if(yearp != NULL)
    *yearp = year;

  if(titlep != NULL)
    *titlep = rstr_alloc(s);
}
Exemplo n.º 20
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       char *errbuf, size_t errlen,
	       video_queue_t *vq, struct vsource_list *vsl,
	       const video_args_t *va0)
{
  video_args_t va = *va0;
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  mp_set_url(mp, va0->canonical_url, va0->parent_url, va0->parent_title);

  usage_event("Play video", 1, USAGE_SEG("format", "RTMP"));

  prop_set(mp->mp_prop_metadata, "format", PROP_SET_STRING, "RTMP");
  prop_set(mp->mp_prop_root, "loading", PROP_SET_INT, 1);

  va.flags |= BACKEND_VIDEO_NO_FS_SCAN;

  rtmp_log_level = RTMP_LOGINFO;
  RTMP_LogSetLevel(rtmp_log_level);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r, mp->mp_cancellable);

  int64_t start = playinfo_get_restartpos(va.canonical_url, va.title, va.resume_mode);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  r.r->Link.lFlags |= RTMP_LF_SWFV;

  if(!RTMP_Connect(r.r, NULL, errbuf, errlen, 5000)) {
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }

  if(start)
    RTMP_SendSeek(r.r, start);
    
  r.mp = mp;
  
  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  if(start > 0) {
    r.seekpos_video = start * 1000;
    r.seekpos_audio = start * 1000;
    mp->mp_seek_base = r.seekpos_video;
    mp->mp_video.mq_seektarget = r.seekpos_video;
    mp->mp_audio.mq_seektarget = r.seekpos_video;
  } else {
    mp->mp_video.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_audio.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_seek_base = 0;
    r.seekpos_audio = AV_NOPTS_VALUE;
    r.seekpos_video = AV_NOPTS_VALUE;
  }

  mp_configure(mp, MP_CAN_PAUSE, MP_BUFFER_DEEP, 0, "video");
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  playinfo_register_play(va.canonical_url, 0);

  r.canonical_url = va.canonical_url;
  r.restartpos_last = -1;

  r.url = url;
  r.va = &va;
  r.is_loading = 1;
  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  if(r.ss)
    sub_scanner_destroy(r.ss);

  if(r.total_duration) {
    int p = mp->mp_seek_base / (r.total_duration * 10);
    if(p >= video_settings.played_threshold) {
      TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
	    p);
      playinfo_register_play(va.canonical_url, 1);
      playinfo_set_restartpos(va.canonical_url, -1, 0);
    } else {
      playinfo_set_restartpos(va.canonical_url, mp->mp_seek_base / 1000, 0);
    }
  }

  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of playback");

  rtmp_free(&r);
  return e;
}
Exemplo n.º 21
0
void
parse_opts(int argc, char **argv)
{
  const char *argv0 = argv[0];

  argv++;
  argc--;

  gconf.showtime_shell_fd = -1;

  while(argc > 0) {
    if(!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help")) {
      printf(APPNAMEUSER" %s\n"
	     "Copyright (C) 2007-2015 Lonelycoder AB\n"
	     "\n"
	     "Usage: %s [options] [<url>]\n"
	     "\n"
	     "  Options:\n"
	     "   -h, --help        - This help text.\n"
	     "   -d                - Enable debug output.\n"
	     "   --no-ui           - Start without UI.\n"
	     "   --fullscreen      - Start in fullscreen mode.\n"
	     "   --libav-log       - Print libav log messages.\n"
	     "   --with-standby    - Enable system standby.\n"
	     "   --with-poweroff   - Enable system power-off.\n"
	     "   -s <path>         - Non-default settings path.\n"
	     "   --ui <ui>         - Use specified user interface.\n"
	     "   -L <ip:host>      - Send log messages to remote <ip:host>.\n"
	     "   --syslog          - Send log messages to syslog.\n"
#if ENABLE_STDIN
	     "   --stdin           - Listen on stdin for events.\n"
#endif
	     "   -v <view>         - Use specific view for <url>.\n"
	     "   --cache <path>    - Set path for cache [%s].\n"
	     "   --persistent <path> - Set path for persistent stuff [%s].\n"
#if ENABLE_HTTPSERVER
	     "   --disable-upnp    - Disable UPNP/DLNA stack.\n"
#endif
	     "   --disable-sd      - Disable service discovery (mDNS, etc).\n"
	     "   -p                - Path to plugin directory to load\n"
	     "                       Intended for plugin development\n"
	     "   --plugin-repo     - URL to plugin repository\n"
	     "                       Intended for plugin development\n"
	     "   -j <path>           Load javascript file\n"
	     "   --skin <skin>     Select skin (for GLW ui)\n"
	     "\n"
	     "  URL is any URL-type supported, "
	     "e.g., \"file:///...\"\n"
	     "\n",
	     htsversion_full,
	     argv0,
	     gconf.cache_path,
	     gconf.persistent_path);
      exit(0);
      argc--;
      argv++;

    } else if(!strcmp(argv[0], "-d")) {
      gconf.trace_level = TRACE_DEBUG;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--libav-log")) {
      gconf.libavlog = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--debug-glw")) {
      gconf.debug_glw = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--show-usage-events")) {
      gconf.show_usage_events = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--no-ui")) {
      gconf.noui = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--fullscreen")) {
      gconf.fullscreen = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--syslog")) {
      gconf.trace_to_syslog = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--stdin")) {
      gconf.listen_on_stdin = 1;
      argc -= 1; argv += 1;
      continue;
#if ENABLE_HTTPSERVER
    } else if(!strcmp(argv[0], "--disable-upnp")) {
      gconf.disable_upnp = 1;
      argc -= 1; argv += 1;
      continue;
#endif
    } else if(!strcmp(argv[0], "--disable-sd")) {
      gconf.disable_sd = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--disable-upgrades")) {
      gconf.disable_upgrades = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--with-standby")) {
      gconf.can_standby = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--with-poweroff")) {
      gconf.can_poweroff = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--with-logout")) {
      gconf.can_logout = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--with-openshell")) {
      gconf.can_open_shell = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--without-exit")) {
      gconf.can_not_exit = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "--with-restart")) {
      gconf.can_restart = 1;
      argc -= 1; argv += 1;
      continue;
    } else if(!strcmp(argv[0], "-p") && argc > 1) {
      strvec_addp(&gconf.devplugins,argv[1]);
      argc -= 2; argv += 2;
      continue;
    } else if(!strcmp(argv[0], "--plugin-repo") && argc > 1) {
      gconf.plugin_repo = argv[1];
      argc -= 2; argv += 2;
      continue;
    } else if(!strcmp(argv[0], "--bypass-ecmascript-acl")) {
      gconf.bypass_ecmascript_acl = 1;
      argc -= 1; argv += 1;
    } else if(!strcmp(argv[0], "--ecmascript") && argc > 1) {
      gconf.load_ecmascript = argv[1];
      argc -= 2; argv += 2;
      continue;
    } else if (!strcmp(argv[0], "-v") && argc > 1) {
      gconf.initial_view = argv[1];
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--cache") && argc > 1) {
      mystrset(&gconf.cache_path, argv[1]);
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--persistent") && argc > 1) {
      mystrset(&gconf.persistent_path, argv[1]);
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--ui") && argc > 1) {
      mystrset(&gconf.ui, argv[1]);
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--skin") && argc > 1) {
      mystrset(&gconf.skin, argv[1]);
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--upgrade-path") && argc > 1) {
      mystrset(&gconf.upgrade_path, argv[1]);
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--showtime-shell-fd") && argc > 1) {
      gconf.showtime_shell_fd = atoi(argv[1]);
      argc -= 2; argv += 2;
    } else if (!strcmp(argv[0], "--proxy") && argc > 1) {
      char *x = mystrdupa(argv[1]);
      char *pstr = strchr(x, ':');

      if(pstr != NULL) {
        *pstr++ = 0;
        gconf.proxy_port = atoi(pstr);
      } else {
        gconf.proxy_port = 1080;
      }
      snprintf(gconf.proxy_host, sizeof(gconf.proxy_host), "%s", x);
      printf("Proxy set to %s:%d\n", gconf.proxy_host, gconf.proxy_port);
      argc -= 2; argv += 2;
#ifdef __APPLE__
    /* ignore -psn argument, process serial number */
    } else if(!strncmp(argv[0], "-psn", 4)) {
      argc -= 1; argv += 1;
      continue;
#endif
    } else
      break;
  }

  if(argc > 0)
    gconf.initial_url = argv[0];
}
Exemplo n.º 22
0
/**
 * Try to figure out if we have a window manager and query some of its
 * capabilities
 */
static void
probe_wm(glw_x11_t *gx11)
{
  int i, format;
  Atom *items, type;
  unsigned long bytes_after, r, nitems;
  unsigned char *prop_return;
  int wm_window_id;
  char *wm_name;

  Atom NET_SUPPORTED =
    XInternAtom(gx11->display, "_NET_SUPPORTED", 0);
  Atom STATE_FS =
    XInternAtom(gx11->display, "_NET_WM_STATE_FULLSCREEN", 0);
  Atom NET_SUPPORTING_WM_CHECK =
    XInternAtom(gx11->display, "_NET_SUPPORTING_WM_CHECK", 0);
  Atom NET_WM_NAME =
    XInternAtom(gx11->display, "_NET_WM_NAME", 0);

  if(XGetWindowProperty(gx11->display, gx11->root, NET_SUPPORTING_WM_CHECK,
			0, 16384, False, AnyPropertyType, &type, &format, &r,
			&bytes_after, &prop_return) != Success ||
     r == 0 || prop_return == NULL) {
    TRACE(TRACE_INFO, "GLW",
	  "No window manager found (NET_SUPPORTING_WM_CHECK not set)");
    return;
  }


  wm_window_id = *(int *)prop_return;
  XFree(prop_return);
  prop_return = NULL;

  if(XGetWindowProperty(gx11->display, wm_window_id, NET_WM_NAME,
			0, 16384, False, AnyPropertyType, &type, &format, &r,
			&bytes_after, &prop_return) != Success || 
     r == 0 || prop_return == NULL) {
    TRACE(TRACE_INFO, "GLW",
	  "No window manager found (NET_WM_NAME not set on wm window)");
    return;
  }

  wm_name = mystrdupa((char *)prop_return);
  XFree(prop_return);
  prop_return = NULL;

  if(XGetWindowProperty(gx11->display, gx11->root, NET_SUPPORTED,
			0, 16384, False, AnyPropertyType, &type, &format,
			&nitems, &bytes_after, &prop_return) != Success ||
     r == 0 || prop_return == NULL) {
    TRACE(TRACE_INFO, "GLW",
	  "No window manager found (NET_SUPPORTING_WM_CHECK not set)");
    return;
  }

  items = (Atom *)prop_return;

  gx11->wm_flags |= GX11_WM_DETECTED;

  for(i = 0; i < nitems; i++) {
    if(items[i] == STATE_FS)
      gx11->wm_flags |= GX11_WM_CAN_FULLSCREEN;
  }

  TRACE(TRACE_DEBUG, "GLW", "Window manager (%s) detected%s",
	wm_name,
	gx11->wm_flags & GX11_WM_CAN_FULLSCREEN ? ", can fullscreen" : "");

  prop_set_string(prop_create(gx11->gr.gr_prop, "windowmanager"),
		  wm_name);

  XFree(prop_return);
}
Exemplo n.º 23
0
event_t *
fa_xmp_playfile(media_pipe_t *mp, FILE *f, char *errbuf, size_t errlen,
                int hold, const char *url, size_t size)
{
    event_t *e = NULL;
    xmp_context ctx = xmp_create_context();
    //  struct xmp_module_info mi;
    struct xmp_frame_info fi;
    char *u = mystrdupa(url);

    mp->mp_audio.mq_stream = 0;
    mp_configure(mp, MP_CAN_PAUSE | MP_CAN_SEEK,
                 MP_BUFFER_SHALLOW, 0, "tracks");
    mp_become_primary(mp);

    if(xmp_load_modulef(ctx, f, u, size) >= 0) {
        if(xmp_start_player(ctx, 44100, 0) == 0) {

            media_buf_t *mb = NULL;
            media_queue_t *mq = &mp->mp_audio;

            while(1) {

                if(mb == NULL) {

                    if(xmp_play_frame(ctx)) {
                        e = event_create_type(EVENT_EOF);
                        break;
                    }
                    xmp_get_frame_info(ctx, &fi);
                    if(fi.loop_count > 0) {
                        e = event_create_type(EVENT_EOF);
                        break;
                    }

                    mb = media_buf_alloc_unlocked(mp, fi.buffer_size);
                    mb->mb_data_type = MB_AUDIO;
                    mb->mb_channels = 2;
                    mb->mb_rate = 44100;
                    mb->mb_pts = fi.time * 1000;
                    mb->mb_drive_clock = 1;
                    memcpy(mb->mb_data, fi.buffer, fi.buffer_size);
                    mp_set_duration(mp, fi.total_time * 1000);
                }

                if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
                    mb = NULL; /* Enqueue succeeded */
                    continue;
                }

                if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {
                    mp_flush(mp, 0);
                    break;

                } else if(event_is_action(e, ACTION_SKIP_BACKWARD) ||
                          event_is_action(e, ACTION_SKIP_FORWARD) ||
                          event_is_action(e, ACTION_STOP)) {
                    mp_flush(mp, 0);
                    break;
                }
                event_release(e);
            }
            xmp_end_player(ctx);
        } else {
            snprintf(errbuf, errlen, "XMP failed to start");
        }
    } else {
        snprintf(errbuf, errlen, "XMP Loading error");
    }
    //  prop_ref_dec(dur);
    xmp_free_context(ctx);
    return e;
}
Exemplo n.º 24
0
int
metadata_filename_to_episode(const char *s,
			     int *seasonp, int *episodep,
			     rstr_t **titlep)
{
  int i, j;
  int len = strlen(s);
  int season = -1;
  int episode = -1;

  // Parse S##E## format

  for(i = 0; i < len; i++) {
    if((s[i] == 's' || s[i] == 'S') && isnum(s[i+1]) && isnum(s[i+2])) {
      int o = 3+i;
      if(s[o] == '.')
	o++;

      if((s[o] == 'e' || s[o] == 'E') && isnum(s[o+1]) && isnum(s[o+2])) {
	season = atoi(s+i+1);
	episode = atoi(s+o+1);
	break;
      }
    }
  }


  if(season == -1 && episode == -1) {
    // Parse ' (#)#x## - '  format
    for(i = 3; i < len - 2; i++) {
      if(s[i] == 'x' && isnum(s[i + 1]) && isnum(s[i + 2]) &&
         s[i + 3] == ' ' && s[i + 4] == '-' && s[i + 5] == ' ') {
        episode = atoi(s + i + 1);

        if(isnum(s[i - 1]) && s[i - 2] == ' ') {
          season = atoi(s + i - 1);
          i--;
          break;
        } else if(isnum(s[i - 1]) && isnum(s[i - 2]) && s[i - 3] == ' ') {
          season = atoi(s + i - 2);
          i-=2;
          break;
        }
      }
    }
  }

  if(season == -1 || episode == -1)
    return -1;

  *seasonp = season;
  *episodep = episode;

  char *t = mystrdupa(s);
  url_deescape(t);

  for(j= 0; j < i; j++) {
    if(t[j] == '.') {
      t[j] = ' ';
    }
  }
  t[j] = 0;

  if(titlep != NULL) {
    if(j)
      *titlep = rstr_alloc(t);
    else
      *titlep = NULL;
  }
  return 0;
}
Exemplo n.º 25
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       int flags, int priority,
	       char *errbuf, size_t errlen,
	       const char *mimetype,
	       const char *canonical_url)
{
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  prop_set_string(mp->mp_prop_type, "video");

  RTMP_LogSetLevel(RTMP_LOGINFO);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r);

  int64_t start = video_get_restartpos(canonical_url);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_Connect(r.r, NULL)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, start)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }
  r.seek_origin = start;
  r.mp = mp;
  r.hold = 0;
  r.lost_focus = 0;
  r.epoch = 1;
  
  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  if(start > 0) {
    r.seekpos = start * 1000;
    r.seekbase = r.seekpos;
    mp->mp_video.mq_seektarget = r.seekpos;
    mp->mp_audio.mq_seektarget = r.seekpos;
  } else {
    mp->mp_video.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_audio.mq_seektarget = AV_NOPTS_VALUE;
    r.seekbase = AV_NOPTS_VALUE;
    r.seekpos = AV_NOPTS_VALUE;
  }

  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_DEEP);
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  metadb_register_play(canonical_url, 0, CONTENT_VIDEO);

  r.canonical_url = canonical_url;
  r.restartpos_last = -1;

  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  if(r.total_duration) {
    int p = r.seekbase / (r.total_duration * 10);
    if(p >= video_settings.played_threshold) {
      TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
	    p);
      metadb_register_play(canonical_url, 1, CONTENT_VIDEO);
      metadb_set_video_restartpos(canonical_url, -1);
    }
  }

  mp_flush(mp, 0);
  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of stream");

  rtmp_free(&r);
  return e;
}
Exemplo n.º 26
0
static image_t *
fa_image_from_video(const char *url0, const image_meta_t *im,
		    char *errbuf, size_t errlen, int *cache_control,
		    cancellable_t *c)
{
  static char *stated_url;
  static fa_stat_t fs;
  time_t stattime = 0;
  time_t mtime = 0;
  image_t *img = NULL;
  char cacheid[512];
  char *url = mystrdupa(url0);
  char *tim = strchr(url, '#');
  const char *siz;
  *tim++ = 0;
  int secs;

  if(!strcmp(tim, "cover"))
    secs = -1;
  else
    secs = atoi(tim);

  hts_mutex_lock(&image_from_video_mutex[0]);

  if(strcmp(url, stated_url ?: "")) {
    free(stated_url);
    stated_url = NULL;
    if(fa_stat(url, &fs, errbuf, errlen)) {
      hts_mutex_unlock(&image_from_video_mutex[0]);
      return NULL;
    }
    stated_url = strdup(url);
  }
  stattime = fs.fs_mtime;
  hts_mutex_unlock(&image_from_video_mutex[0]);

  if(im->im_req_width < 100 && im->im_req_height < 100) {
    siz = "min";
  } else if(im->im_req_width < 200 && im->im_req_height < 200) {
    siz = "mid";
  } else {
    siz = "max";
  }

  snprintf(cacheid, sizeof(cacheid), "%s-%s", url0, siz);
  buf_t *b = blobcache_get(cacheid, "videothumb", 0, 0, NULL, &mtime);
  if(b != NULL && mtime == stattime) {
    img = image_coded_create_from_buf(b, IMAGE_JPEG);
    buf_release(b);
    return img;
  }
  buf_release(b);

  if(ONLY_CACHED(cache_control)) {
    snprintf(errbuf, errlen, "Not cached");
    return NULL;
  }

  hts_mutex_lock(&image_from_video_mutex[1]);
  img = fa_image_from_video2(url, im, cacheid, errbuf, errlen,
                             secs, stattime, c);
  hts_mutex_unlock(&image_from_video_mutex[1]);
  if(img != NULL)
    img->im_flags |= IMAGE_ADAPTED;
  return img;
}
Exemplo n.º 27
0
static int
gmefile_scandir(fa_dir_t *fd, const char *url, char *errbuf, size_t errlen)
{
  char *p, *fpath = mystrdupa(url);
  char name[32];
  char turl[URL_MAX];
  int tracks, i;
  fa_dir_entry_t *fde;
  const char *title;
  Music_Emu *emu;
  gme_info_t *info;
  gme_err_t err;

  if((p = strrchr(fpath, '/')) == NULL) {
    snprintf(errbuf, errlen, "Invalid filename");
    return -1;
  }

  *p = 0;

  buf_t *b;
  if((b = fa_load(fpath,  NULL, errbuf, errlen, NULL,
		  0, NULL, NULL)) == NULL)
    return -1;

  err = gme_open_data(b->b_ptr, b->b_size, &emu, gme_info_only);
  buf_release(b);
  if(err != NULL)
    return 0;

  tracks = gme_track_count(emu);
  
  for(i = 0; i < tracks; i++) {

    snprintf(turl, sizeof(turl), "gmeplayer:%s/%d", fpath, i + 1);

    err = gme_track_info(emu, &info, i);

    if(err == NULL && info->song[0]) {
      title = info->song;
    } else {
      snprintf(name, sizeof(name), "Track %02d", i + 1);
      title = name;
    }

      
    fde = fa_dir_add(fd, turl, title, CONTENT_AUDIO);

    fde->fde_probestatus = FDE_PROBE_DEEP;

    fde->fde_metadata = prop_create_root("metadata");
    prop_set_string(prop_create(fde->fde_metadata, "title"), title);

    if(err == NULL) {
      if(info->game[0])
	prop_set_string(prop_create(fde->fde_metadata, "album"), info->game);
      if(info->author[0])
	prop_set_string(prop_create(fde->fde_metadata, "artist"), info->author);

      prop_set_float(prop_create(fde->fde_metadata, "duration"), 
		     info->play_length / 1000.0);

      gme_free_info(info);
    }
  }

  gme_delete(emu);
  return 0;
}
Exemplo n.º 28
0
void
load_site_news(void)
{
#if ENABLE_WEBPOPUP
  struct http_header_list response_headers;
  buf_t *b;
  char errbuf[512];
  b = fa_load("https://movian.tv/projects/movian/news.json",
              FA_LOAD_FLAGS(FA_DISABLE_AUTH | FA_COMPRESSION),
              FA_LOAD_RESPONSE_HEADERS(&response_headers),
              FA_LOAD_ERRBUF(errbuf, sizeof(errbuf)),
              NULL);
  if(b == NULL) {
    TRACE(TRACE_DEBUG, "News", "Unable to load news -- %s", errbuf);
    return;
  }

  const char *dateheader = http_header_get(&response_headers, "date");
  if(dateheader == NULL) {
    buf_release(b);
    http_headers_free(&response_headers);
    return;
  }
  dateheader = mystrdupa(dateheader);
  http_headers_free(&response_headers);


  htsmsg_t *newsinfo = htsmsg_store_load("sitenews");
  time_t no_news_before;

  if(newsinfo == NULL)
    newsinfo = htsmsg_create_map();

  no_news_before = htsmsg_get_u32_or_default(newsinfo, "nothingbefore", 0);

  if(no_news_before == 0) {
    if(http_ctime(&no_news_before, dateheader)) {
      buf_release(b);
      htsmsg_release(newsinfo);
      return;
    }

    htsmsg_add_u32(newsinfo, "nothingbefore", no_news_before);
    htsmsg_store_save(newsinfo, "sitenews");
    htsmsg_release(newsinfo);
  }

  htsmsg_t *doc = htsmsg_json_deserialize(buf_cstr(b));
  buf_release(b);
  if(doc == NULL) {
    return;
  }

  hts_mutex_lock(&news_mutex);

  htsmsg_t *news = htsmsg_get_list(doc, "news");
  if(news != NULL) {
    htsmsg_field_t *f;
    HTSMSG_FOREACH(f, news) {
      htsmsg_t *entry;
      if((entry = htsmsg_get_map_by_field(f)) == NULL)
        continue;

      const char *title = htsmsg_get_str(entry, "title");
      const char *created_on = htsmsg_get_str(entry, "created_on");
      int id = htsmsg_get_u32_or_default(entry, "id", 0);
      if(created_on == NULL || title == NULL || id == 0)
        continue;

      time_t t;

      if(parse_created_on_time(&t, created_on))
        continue;

      if(t < no_news_before)
        continue;

      char idstr[64];
      snprintf(idstr, sizeof(idstr), "sitenews:%d", id);
      prop_t *p = add_news_locked(idstr, title, NULL, "Read more", idstr);
      if(p != NULL) {
        prop_subscribe(PROP_SUB_TRACK_DESTROY,
                       PROP_TAG_CALLBACK, open_news, p,
                       PROP_TAG_ROOT, prop_create(p, "eventSink"),
                       PROP_TAG_MUTEX, &news_mutex,
                       NULL);
      }
    }
Exemplo n.º 29
0
static event_t *
rtmp_playvideo(const char *url0, media_pipe_t *mp,
	       char *errbuf, size_t errlen,
	       video_queue_t *vq, struct vsource_list *vsl,
	       const video_args_t *va0)
{
  video_args_t va = *va0;
  rtmp_t r = {0};
  event_t *e;
  char *url = mystrdupa(url0);

  va.flags |= BACKEND_VIDEO_NO_FS_SCAN;

  prop_set_string(mp->mp_prop_type, "video");

  rtmp_log_level = RTMP_LOGINFO;
  RTMP_LogSetLevel(rtmp_log_level);

  r.r = RTMP_Alloc();
  RTMP_Init(r.r);

  int64_t start = 0;

  if(va.flags & BACKEND_VIDEO_RESUME ||
     (video_settings.resume_mode == VIDEO_RESUME_YES &&
      !(va.flags & BACKEND_VIDEO_START_FROM_BEGINNING)))
    start = video_get_restartpos(va.canonical_url);

  if(!RTMP_SetupURL(r.r, url)) {
    snprintf(errbuf, errlen, "Unable to setup RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  r.r->Link.lFlags |= RTMP_LF_SWFV;

  if(!RTMP_Connect(r.r, NULL)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-session");
    rtmp_free(&r);
    return NULL;
  }

  if(!RTMP_ConnectStream(r.r, 0)) {
    snprintf(errbuf, errlen, "Unable to connect RTMP-stream");
    rtmp_free(&r);
    return NULL;
  }

  if(start)
    RTMP_SendSeek(r.r, start);
    
  r.mp = mp;
  
  mp->mp_audio.mq_stream = 0;
  mp->mp_video.mq_stream = 0;

  if(start > 0) {
    r.seekpos_video = start * 1000;
    r.seekpos_audio = start * 1000;
    mp->mp_seek_base = r.seekpos_video;
    mp->mp_video.mq_seektarget = r.seekpos_video;
    mp->mp_audio.mq_seektarget = r.seekpos_video;
  } else {
    mp->mp_video.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_audio.mq_seektarget = AV_NOPTS_VALUE;
    mp->mp_seek_base = 0;
    r.seekpos_audio = AV_NOPTS_VALUE;
    r.seekpos_video = AV_NOPTS_VALUE;
  }

  mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_DEEP, 0);
  mp->mp_max_realtime_delay = (r.r->Link.timeout - 1) * 1000000;

  mp_become_primary(mp);

  metadb_register_play(va.canonical_url, 0, CONTENT_VIDEO);

  r.canonical_url = va.canonical_url;
  r.restartpos_last = -1;

  sub_scanner_t *ss =
    sub_scanner_create(url, mp->mp_prop_subtitle_tracks, &va, 0);

  e = rtmp_loop(&r, mp, url, errbuf, errlen);

  sub_scanner_destroy(ss);

  if(r.total_duration) {
    int p = mp->mp_seek_base / (r.total_duration * 10);
    if(p >= video_settings.played_threshold) {
      TRACE(TRACE_DEBUG, "RTMP", "Playback reached %d%%, counting as played",
	    p);
      metadb_register_play(va.canonical_url, 1, CONTENT_VIDEO);
      metadb_set_video_restartpos(va.canonical_url, -1);
    }
  }

  mp_flush(mp, 0);
  mp_shutdown(mp);

  TRACE(TRACE_DEBUG, "RTMP", "End of stream");

  rtmp_free(&r);
  return e;
}
Exemplo n.º 30
0
Arquivo: sid.c Projeto: pvc1/showtime
/**
 * Play given track.
 *
 * We only expect this to be called from the playqueue system.
 */
static event_t *
be_sid2player_play(const char *url0, media_pipe_t *mp,
                   char *errbuf, size_t errlen, int hold,
                   const char *mimetype)
{
    media_queue_t *mq = &mp->mp_audio;
    char *url, *p;
    int sample = 0, lost_focus = 0;
    media_buf_t *mb = NULL;
    event_t *e;
    int subsong;


    void *player;
    void *data;
    struct fa_stat fs;


    url0 += strlen("sidplayer:");

    url = mystrdupa(url0);
    p = strrchr(url, '/');
    if(p == NULL) {
        snprintf(errbuf, errlen, "Invalid filename");
        return NULL;
    }

    *p++= 0;
    subsong = atoi(p);

    if((data = fa_quickload(url, &fs, NULL, errbuf, errlen)) == NULL)
        return NULL;

    player = sidcxx_load(data, fs.fs_size, subsong, errbuf, errlen);
    free(data);
    if(player == NULL)
        return NULL;

    mp_set_playstatus_by_hold(mp, hold, NULL);
    mp->mp_audio.mq_stream = 0;
    mp_configure(mp, MP_PLAY_CAPS_PAUSE, MP_BUFFER_NONE);
    mp_become_primary(mp);


    while(1) {

        if(mb == NULL) {

            mb = media_buf_alloc();
            mb->mb_data_type = MB_AUDIO;
            mb->mb_channels = 2;
            mb->mb_size = sizeof(int16_t) * CHUNK_SIZE * mb->mb_channels;
            mb->mb_data = malloc(mb->mb_size);
            mb->mb_rate = 44100;

            mb->mb_time = sample * 1000000LL / mb->mb_rate;
            sample += CHUNK_SIZE;

            int16_t *samples = mb->mb_data;

            sidcxx_play(player, samples,
                        CHUNK_SIZE * sizeof(int16_t) * mb->mb_channels);

            // Crossmix 25%

            int i, l, r, L, R;
            for(i = 0; i < CHUNK_SIZE; i++) {
                l = samples[i * 2 + 0];
                r = samples[i * 2 + 1];

                L = 3 * l + r * 2;
                R = 3 * r + l * 2;

                L = L / 4;
                R = R / 4;

                if(L > 32767)
                    L = 32767;
                if(L < -32768)
                    L = -32768;

                if(R > 32767)
                    R = 32767;
                if(R < -32768)
                    R = -32768;

                samples[i * 2 + 0] = L;
                samples[i * 2 + 1] = R;
            }
        }

        if((e = mb_enqueue_with_events(mp, mq, mb)) == NULL) {
            mb = NULL; /* Enqueue succeeded */
            continue;
        }

        if(event_is_type(e, EVENT_PLAYQUEUE_JUMP)) {
            mp_flush(mp, 0);
            break;
        } else if(event_is_action(e, ACTION_PLAYPAUSE) ||
                  event_is_action(e, ACTION_PLAY) ||
                  event_is_action(e, ACTION_PAUSE)) {

            hold = action_update_hold_by_event(hold, e);
            mp_send_cmd_head(mp, mq, hold ? MB_CTRL_PAUSE : MB_CTRL_PLAY);
            lost_focus = 0;
            mp_set_playstatus_by_hold(mp, hold, NULL);

        } else if(event_is_type(e, EVENT_MP_NO_LONGER_PRIMARY)) {

            hold = 1;
            lost_focus = 1;
            mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
            mp_set_playstatus_by_hold(mp, hold, e->e_payload);

        } else if(event_is_type(e, EVENT_MP_IS_PRIMARY)) {

            if(lost_focus) {
                hold = 0;
                lost_focus = 0;
                mp_send_cmd_head(mp, mq, MB_CTRL_PLAY);
                mp_set_playstatus_by_hold(mp, hold, NULL);
            }

        } else if(event_is_type(e, EVENT_INTERNAL_PAUSE)) {

            hold = 1;
            lost_focus = 0;
            mp_send_cmd_head(mp, mq, MB_CTRL_PAUSE);
            mp_set_playstatus_by_hold(mp, hold, e->e_payload);

        } else if(event_is_action(e, ACTION_PREV_TRACK) ||
                  event_is_action(e, ACTION_NEXT_TRACK) ||
                  event_is_action(e, ACTION_STOP)) {
            mp_flush(mp, 0);
            break;
        }
        event_release(e);
    }

    sidcxx_stop(player);

    return e;
}