data-mp3.c
author nathan
Fri, 02 Jan 2009 13:46:58 +0100
branchtrunk
changeset 19 306cc35c7faa
parent 0 474a1293c3c0
child 22 93aaf15c145a
permissions -rw-r--r--
add commandline option for user defined default background image
nathan@0
     1
/*
nathan@0
     2
 * MP3/MPlayer plugin to VDR (C++)
nathan@0
     3
 *
nathan@0
     4
 * (C) 2001-2006 Stefan Huelswitt <s.huelswitt@gmx.de>
nathan@0
     5
 *
nathan@0
     6
 * This code is free software; you can redistribute it and/or
nathan@0
     7
 * modify it under the terms of the GNU General Public License
nathan@0
     8
 * as published by the Free Software Foundation; either version 2
nathan@0
     9
 * of the License, or (at your option) any later version.
nathan@0
    10
 *
nathan@0
    11
 * This code is distributed in the hope that it will be useful,
nathan@0
    12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nathan@0
    13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nathan@0
    14
 * GNU General Public License for more details.
nathan@0
    15
 *
nathan@0
    16
 * You should have received a copy of the GNU General Public License
nathan@0
    17
 * along with this program; if not, write to the Free Software
nathan@0
    18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
nathan@0
    19
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
nathan@0
    20
 */
nathan@0
    21
nathan@0
    22
#include <stdlib.h>
nathan@0
    23
#include <stdio.h>
nathan@0
    24
#include <unistd.h>
nathan@0
    25
nathan@0
    26
#include "common.h"
nathan@0
    27
#include "data-mp3.h"
nathan@0
    28
#include "data.h"
nathan@0
    29
#include "decoder.h"
nathan@0
    30
nathan@0
    31
#define DEBUG_IMAGE
nathan@0
    32
nathan@0
    33
#ifdef DEBUG_IMAGE
nathan@0
    34
#define di(x) { (x); }
nathan@0
    35
#else
nathan@0
    36
#define di(x) ; 
nathan@0
    37
#endif
nathan@0
    38
nathan@0
    39
const char *imagecache = "/var/cache/images/mp3";
nathan@0
    40
const char *imageconv  = "image_convert.sh";
nathan@19
    41
const char *def_usr_img = 0;
nathan@0
    42
nathan@0
    43
// image suffixes to search
nathan@0
    44
const char *img_suff[] = { "jpg","png","gif",0 };
nathan@0
    45
// exclude list for instant playlist creation
nathan@0
    46
const char *excl_pl[] = { "*"PLAYLISTEXT,"*.jpg","*.gif","*.png",0 };
nathan@0
    47
// exclude list for song browser
nathan@0
    48
const char *excl_br[] = { ".*","*.jpg","*.gif","*.png",0 };
nathan@0
    49
nathan@0
    50
// --- cImageConvert -----------------------------------------------------------
nathan@0
    51
nathan@0
    52
class cImageConvert : private cThread {
nathan@0
    53
private:
nathan@0
    54
  char *image;
nathan@0
    55
  enum eStatus { stNone, stRun, stFin };
nathan@0
    56
  eStatus status;
nathan@0
    57
protected:
nathan@0
    58
  virtual void Action(void);
nathan@0
    59
public:
nathan@0
    60
  cImageConvert(void);
nathan@0
    61
  ~cImageConvert();
nathan@0
    62
  bool Convert(const char *Image);
nathan@0
    63
  bool Status(void);
nathan@0
    64
  };
nathan@0
    65
nathan@0
    66
cImageConvert::cImageConvert(void)
nathan@0
    67
{
nathan@0
    68
  image=0; status=stNone;
nathan@0
    69
}
nathan@0
    70
nathan@0
    71
cImageConvert::~cImageConvert()
nathan@0
    72
{
nathan@0
    73
  if(status==stRun) Cancel(10);
nathan@0
    74
  free(image);
nathan@0
    75
}
nathan@0
    76
nathan@0
    77
bool cImageConvert::Convert(const char *Image)
nathan@0
    78
{
nathan@0
    79
  if(status==stNone) {
nathan@0
    80
    image=strdup(Image);
nathan@0
    81
    status=stRun;
nathan@0
    82
    Start();
nathan@0
    83
    return true;
nathan@0
    84
    }
nathan@0
    85
  return false;
nathan@0
    86
}
nathan@0
    87
nathan@0
    88
bool cImageConvert::Status(void)
nathan@0
    89
{
nathan@0
    90
  if(status==stRun && !Active()) status=stFin;
nathan@0
    91
  return status==stFin;
nathan@0
    92
}
nathan@0
    93
nathan@0
    94
void cImageConvert::Action(void)
nathan@0
    95
{
nathan@0
    96
  nice(3);
nathan@0
    97
  char *m, *cmd, *qp, *qm;
nathan@0
    98
  asprintf(&m,"%s%s.mpg",imagecache,image);
nathan@0
    99
  di(printf("image: convert started %s -> %s\n",image,m))
nathan@0
   100
  asprintf(&cmd,"%s \"%s\" \"%s\"",imageconv,qp=Quote(image),qm=Quote(m));
nathan@0
   101
  int r=system(cmd);
nathan@0
   102
  if(r!=0) di(printf("image: convert returned with code %d. Failed?\n",r))
nathan@0
   103
  free(cmd); free(qp); free(qm); free(m);
nathan@0
   104
  di(printf("image: convert finished\n"))
nathan@0
   105
  status=stFin;
nathan@0
   106
}
nathan@0
   107
nathan@0
   108
// --- cSong -------------------------------------------------------------------
nathan@0
   109
nathan@0
   110
cSong::cSong(cFileObj *Obj)
nathan@0
   111
{
nathan@0
   112
  obj=new cFileObj(Obj);
nathan@0
   113
  Init();
nathan@0
   114
}
nathan@0
   115
nathan@0
   116
cSong::cSong(cFileSource *Source, const char *Subdir, const char *Name)
nathan@0
   117
{
nathan@0
   118
  obj=new cFileObj(Source,Subdir,Name,otFile);
nathan@0
   119
  Init();
nathan@0
   120
}
nathan@0
   121
nathan@0
   122
cSong::cSong(cSong *Song)
nathan@0
   123
{
nathan@0
   124
  obj=new cFileObj(Song->obj);
nathan@0
   125
  Init();
nathan@0
   126
}
nathan@0
   127
nathan@0
   128
cSong::~cSong()
nathan@0
   129
{
nathan@0
   130
  delete conv;
nathan@0
   131
  delete decoder;
nathan@0
   132
  obj->Source()->Unblock();
nathan@0
   133
  delete obj;
nathan@0
   134
  free((char *)image);
nathan@0
   135
}
nathan@0
   136
nathan@0
   137
void cSong::Init(void)
nathan@0
   138
{
nathan@0
   139
  decoder=0; user=0; image=0; conv=0; queueStat=0;
nathan@0
   140
  fromDOS=decoderFailed=false;
nathan@0
   141
  obj->Source()->Block();
nathan@0
   142
}
nathan@0
   143
nathan@0
   144
#if APIVERSNUM >= 10315
nathan@0
   145
int cSong::Compare(const cListObject &ListObject) const
nathan@0
   146
#else
nathan@0
   147
bool cSong::operator<(const cListObject &ListObject)
nathan@0
   148
#endif
nathan@0
   149
{
nathan@0
   150
  cSong *song=(cSong *)&ListObject;
nathan@0
   151
#if APIVERSNUM >= 10315
nathan@0
   152
  return strcasecmp(obj->Path(),song->obj->Path());
nathan@0
   153
#else
nathan@0
   154
  return strcasecmp(obj->Path(),song->obj->Path())<0;
nathan@0
   155
#endif
nathan@0
   156
}
nathan@0
   157
nathan@0
   158
cSongInfo *cSong::Info(bool get)
nathan@0
   159
{
nathan@0
   160
  Decoder();
nathan@0
   161
  cSongInfo *si=0;
nathan@0
   162
  if(decoder) si=decoder->SongInfo(get);
nathan@0
   163
  return si;
nathan@0
   164
}
nathan@0
   165
nathan@0
   166
cDecoder *cSong::Decoder(void)
nathan@0
   167
{
nathan@0
   168
  decLock.Lock();
nathan@0
   169
  if(!decoder && !decoderFailed) {
nathan@0
   170
    decoder=cDecoders::FindDecoder(obj);
nathan@0
   171
    if(!decoder) decoderFailed=true;
nathan@0
   172
    }
nathan@0
   173
  decLock.Unlock();
nathan@0
   174
  return decoder;
nathan@0
   175
}
nathan@0
   176
nathan@0
   177
void cSong::Convert(void)
nathan@0
   178
{
nathan@0
   179
  char *Name=Convert2Unix(obj->Name());
nathan@0
   180
  obj->SetName(Name);
nathan@0
   181
  fromDOS=true;
nathan@0
   182
  free(Name);
nathan@0
   183
}
nathan@0
   184
nathan@0
   185
char *cSong::Convert2Unix(const char *name) const
nathan@0
   186
{
nathan@0
   187
  char *Name=strdup(name);
nathan@0
   188
  char *p=Name;
nathan@0
   189
  while(*p) {
nathan@0
   190
    if(*p=='/') *p='?';
nathan@0
   191
    if(*p=='\\') *p='/';
nathan@0
   192
    p++;
nathan@0
   193
    }
nathan@0
   194
  return Name;
nathan@0
   195
}
nathan@0
   196
nathan@0
   197
/*
nathan@0
   198
char *cSong::Convert2Dos(const char *name)
nathan@0
   199
{
nathan@0
   200
  char *Name=strdup(name);
nathan@0
   201
  char *p=Name;
nathan@0
   202
  while(*p) {
nathan@0
   203
    if(*p=='\\') *p='?';
nathan@0
   204
    if(*p=='/') *p='\\';
nathan@0
   205
    p++;
nathan@0
   206
    }
nathan@0
   207
  return Name;
nathan@0
   208
}
nathan@0
   209
*/
nathan@0
   210
nathan@0
   211
bool cSong::Parse(char *s, const char *reldir) const
nathan@0
   212
{
nathan@0
   213
  s=skipspace(stripspace(s));
nathan@0
   214
  if(*s) {
nathan@0
   215
    if(s[0]=='/' || !reldir)
nathan@0
   216
      obj->SplitAndSet(s);
nathan@0
   217
    else {
nathan@0
   218
      s=AddPath(reldir,s);
nathan@0
   219
      obj->SplitAndSet(s);
nathan@0
   220
      free(s);
nathan@0
   221
      }
nathan@0
   222
    return true;
nathan@0
   223
    }
nathan@0
   224
  return false;
nathan@0
   225
}
nathan@0
   226
nathan@0
   227
bool cSong::Save(FILE *f, const char *reldir) const
nathan@0
   228
{
nathan@0
   229
  const char *path=obj->Path();
nathan@0
   230
  if(reldir) {
nathan@0
   231
    int l=strlen(reldir);
nathan@0
   232
    if(!strncasecmp(path,reldir,l)) path+=l+1;
nathan@0
   233
    }
nathan@0
   234
  return fprintf(f,"%s\n",path)>0;
nathan@0
   235
}
nathan@0
   236
nathan@0
   237
bool cSong::FindImage(void)
nathan@0
   238
{
nathan@0
   239
  if(image) return true;
nathan@0
   240
nathan@0
   241
  char base[strlen(obj->Path())+32];
nathan@0
   242
  strcpy(base,obj->Path());
nathan@0
   243
  di(printf("image: checking image for %s\n",obj->Path()))
nathan@0
   244
nathan@0
   245
  // song specific image
nathan@0
   246
  char *m=rindex(base,'.');
nathan@0
   247
  if(m) *m=0;
nathan@0
   248
  if((image=CheckImage(base))) return true;
nathan@0
   249
nathan@0
   250
  // album specific image in song directory
nathan@0
   251
  if(!(m=rindex(base,'/'))) m=base-1;
nathan@0
   252
  strcpy(m+1,"cover");
nathan@0
   253
  if((image=CheckImage(base))) return true;
nathan@0
   254
nathan@0
   255
  // artist specific image in parent directory
nathan@0
   256
  if((m=rindex(base,'/'))) {
nathan@0
   257
    *m=0;
nathan@0
   258
    if(!(m=rindex(base,'/'))) m=base-1;
nathan@0
   259
    strcpy(m+1,"artist");
nathan@0
   260
    if((image=CheckImage(base))) return true;
nathan@0
   261
    }
nathan@0
   262
nathan@0
   263
  // default image in source basedir
nathan@0
   264
  if((image=CheckImage("background"))) return true;
nathan@0
   265
nathan@19
   266
  // default user supplied image
nathan@19
   267
  if(def_usr_img && (image=strdup(def_usr_img))) return true;
nathan@19
   268
nathan@0
   269
  di(printf("image: no image for %s\n",obj->Path()))
nathan@0
   270
  return false;
nathan@0
   271
}
nathan@0
   272
nathan@0
   273
const char *cSong::CheckImage(const char *base) const
nathan@0
   274
{
nathan@0
   275
  char *p;
nathan@0
   276
  int n;
nathan@0
   277
  asprintf(&p,"%s/%s.%n     ",obj->Source()->BaseDir(),base,&n);
nathan@0
   278
  for(const char **s=img_suff; *s; s++) {
nathan@0
   279
#ifdef DEBUG
nathan@0
   280
    if(strlen(*s)>5) printf("ERROR: buffer overflow in CheckImage ext=%s\n",*s);
nathan@0
   281
#endif
nathan@0
   282
    strcpy(&p[n],*s);
nathan@0
   283
    di(printf("image: check %s\n",p))
nathan@0
   284
    if(!access(p,R_OK)) {
nathan@0
   285
      di(printf("image: found\n"))
nathan@0
   286
      return p;
nathan@0
   287
      }
nathan@0
   288
    }
nathan@0
   289
  free(p);
nathan@0
   290
  return 0;
nathan@0
   291
}
nathan@0
   292
nathan@0
   293
#include "data-mp3-image.c"
nathan@0
   294
extern void PropagateImage(const char *image);
nathan@0
   295
nathan@0
   296
bool cSong::Image(unsigned char * &mem, int &len)
nathan@0
   297
{
nathan@0
   298
  mem=0;
nathan@0
   299
  if(queueStat>0) {
nathan@0
   300
    if(!conv->Status()) {
nathan@0
   301
      di(printf("image: still queued\n"))
nathan@0
   302
      return false;
nathan@0
   303
      }
nathan@0
   304
    queueStat=-1;
nathan@0
   305
    delete conv; conv=0;
nathan@0
   306
    }
nathan@0
   307
nathan@0
   308
  int res=0;
nathan@0
   309
  if(image || FindImage()) {
nathan@0
   310
    di(printf("image: loading image %s\n",image))
nathan@0
   311
    char *m;
nathan@0
   312
    asprintf(&m,"%s%s.mpg",imagecache,image);
nathan@0
   313
    if(access(m,R_OK)) {
nathan@0
   314
      di(printf("image: not cached\n"))
nathan@0
   315
      if(queueStat<0) {
nathan@0
   316
        di(printf("image: obviously convert failed...\n"))
nathan@0
   317
        }
nathan@0
   318
      else {
nathan@0
   319
        if(!conv) conv=new cImageConvert;
nathan@0
   320
        if(conv && conv->Convert(image)) {
nathan@0
   321
          di(printf("image: convert queued\n"))
nathan@0
   322
          queueStat=1;
nathan@0
   323
          res=-1;
nathan@0
   324
          }
nathan@0
   325
        else {
nathan@0
   326
          di(printf("image: queueing failed\n"))
nathan@0
   327
          queueStat=-1;
nathan@0
   328
          }
nathan@0
   329
        }
nathan@0
   330
      }
nathan@0
   331
    else {
nathan@0
   332
      di(printf("image: cached\n"))
nathan@0
   333
      int f=open(m,O_RDONLY);
nathan@0
   334
      if(f>=0) {
nathan@0
   335
        struct stat64 st;
nathan@0
   336
        fstat64(f,&st);
nathan@0
   337
        len=st.st_size;
nathan@0
   338
        mem=MALLOC(unsigned char,len);
nathan@0
   339
        if(mem) {
nathan@0
   340
          if(read(f,mem,len)==len) res=1;
nathan@0
   341
          else free(mem);
nathan@0
   342
          }
nathan@0
   343
        close(f);
nathan@0
   344
        }
nathan@0
   345
      }
nathan@0
   346
    free(m);
nathan@0
   347
    }
nathan@0
   348
nathan@0
   349
  PropagateImage(res==1 ? image : 0);
nathan@0
   350
nathan@0
   351
  if(res<=0) {
nathan@0
   352
    di(printf("image: using static default image\n"))
nathan@0
   353
    len=sizeof(defaultImage);
nathan@0
   354
    mem=MALLOC(unsigned char,len);
nathan@0
   355
    if(mem) {
nathan@0
   356
      memcpy(mem,defaultImage,len);
nathan@0
   357
      }
nathan@0
   358
    }
nathan@0
   359
  return res>=0;
nathan@0
   360
}
nathan@0
   361
nathan@0
   362
// -- cPlayList --------------------------------------------------------------
nathan@0
   363
nathan@0
   364
cPlayList::cPlayList(cFileObj *Obj)
nathan@0
   365
{
nathan@0
   366
  obj=new cFileObj(Obj);
nathan@0
   367
  Init();
nathan@0
   368
}
nathan@0
   369
nathan@0
   370
cPlayList::cPlayList(cFileSource *Source, const char *Subdir, const char *Name)
nathan@0
   371
{
nathan@0
   372
  obj=new cFileObj(Source,Subdir,Name,otFile);
nathan@0
   373
  Init();
nathan@0
   374
}
nathan@0
   375
nathan@0
   376
cPlayList::cPlayList(cPlayList *List)
nathan@0
   377
{
nathan@0
   378
  obj=new cFileObj(List->obj);
nathan@0
   379
  Init();
nathan@0
   380
}
nathan@0
   381
nathan@0
   382
cPlayList::~cPlayList()
nathan@0
   383
{
nathan@0
   384
  free(basename);
nathan@0
   385
  free(extbuffer);
nathan@0
   386
  obj->Source()->Unblock();
nathan@0
   387
  delete obj;
nathan@0
   388
}
nathan@0
   389
nathan@0
   390
void cPlayList::Init(void)
nathan@0
   391
{
nathan@0
   392
  extbuffer=basename=0;
nathan@0
   393
  isWinAmp=false;
nathan@0
   394
  obj->Source()->Block();
nathan@0
   395
  Set();
nathan@0
   396
}
nathan@0
   397
nathan@0
   398
void cPlayList::Set(void)
nathan@0
   399
{
nathan@0
   400
  free(basename); basename=0;
nathan@0
   401
  if(obj->Name()) {
nathan@0
   402
    basename=strdup(obj->Name());
nathan@0
   403
    int l=strlen(basename)-strlen(PLAYLISTEXT);
nathan@0
   404
    if(l>0 && !strcasecmp(basename+l,PLAYLISTEXT)) basename[l]=0;
nathan@0
   405
    }
nathan@0
   406
}
nathan@0
   407
nathan@0
   408
#if APIVERSNUM >= 10315
nathan@0
   409
int cPlayList::Compare(const cListObject &ListObject) const
nathan@0
   410
#else
nathan@0
   411
bool cPlayList::operator<(const cListObject &ListObject)
nathan@0
   412
#endif
nathan@0
   413
{
nathan@0
   414
  cPlayList *list=(cPlayList *)&ListObject;
nathan@0
   415
#if APIVERSNUM >= 10315
nathan@0
   416
  return strcasecmp(obj->Name(),list->obj->Name());
nathan@0
   417
#else
nathan@0
   418
  return strcasecmp(obj->Name(),list->obj->Name())<0;
nathan@0
   419
#endif
nathan@0
   420
}
nathan@0
   421
nathan@0
   422
bool cPlayList::Load(void)
nathan@0
   423
{
nathan@0
   424
  Clear();
nathan@0
   425
  bool result=false;
nathan@0
   426
  FILE *f=fopen(obj->FullPath(),"r");
nathan@0
   427
  if(f) {
nathan@0
   428
    char buffer[512];
nathan@0
   429
    result=true;
nathan@0
   430
    while(fgets(buffer,sizeof(buffer),f)>0) {
nathan@0
   431
      if(buffer[0]=='#') {
nathan@0
   432
        if(!strncmp(buffer,WINAMPEXT,strlen(WINAMPEXT))) {
nathan@0
   433
          d(printf("mp3: detected WinAmp style playlist\n"))
nathan@0
   434
          isWinAmp=true;
nathan@0
   435
          }
nathan@0
   436
        continue;
nathan@0
   437
        }
nathan@0
   438
      if(!isempty(buffer)) {
nathan@0
   439
        cSong *song=new cSong(obj->Source(),0,0);
nathan@0
   440
        if(song->Parse(buffer,obj->Subdir())) Add(song);
nathan@0
   441
        else {
nathan@0
   442
          esyslog("error loading playlist %s\n",obj->FullPath());
nathan@0
   443
          delete song;
nathan@0
   444
          result=false;
nathan@0
   445
          break;
nathan@0
   446
          }
nathan@0
   447
        }
nathan@0
   448
      }
nathan@0
   449
    fclose(f);
nathan@0
   450
    }
nathan@0
   451
  else LOG_ERROR_STR(obj->FullPath());
nathan@0
   452
nathan@0
   453
  if(result && isWinAmp) {
nathan@0
   454
    cSong *song=First();
nathan@0
   455
    while(song) {   // if this is a WinAmp playlist, convert \ to /
nathan@0
   456
      song->Convert();
nathan@0
   457
      song=cList<cSong>::Next(song);
nathan@0
   458
      }
nathan@0
   459
    }
nathan@0
   460
  return result;
nathan@0
   461
}
nathan@0
   462
nathan@0
   463
bool cPlayList::Save(void)
nathan@0
   464
{
nathan@0
   465
  bool result=true;
nathan@0
   466
  cSafeFile f(obj->FullPath());
nathan@0
   467
  if(f.Open()) {
nathan@0
   468
    cSong *song=First();
nathan@0
   469
    while(song) {
nathan@0
   470
      if(!song->Save(f,obj->Subdir())) {
nathan@0
   471
         result=false;
nathan@0
   472
         break;
nathan@0
   473
         }
nathan@0
   474
      song=cList<cSong>::Next(song);
nathan@0
   475
      }
nathan@0
   476
    if(!f.Close()) result=false;
nathan@0
   477
    }
nathan@0
   478
  else result=false;
nathan@0
   479
  return result;
nathan@0
   480
}
nathan@0
   481
 
nathan@0
   482
bool cPlayList::Exists(void)
nathan@0
   483
{
nathan@0
   484
  return obj->Exists();
nathan@0
   485
}
nathan@0
   486
nathan@0
   487
bool cPlayList::TestName(const char *newName)
nathan@0
   488
{
nathan@0
   489
  return obj->TestName(AddExt(newName,PLAYLISTEXT));
nathan@0
   490
}
nathan@0
   491
nathan@0
   492
bool cPlayList::Rename(const char *newName)
nathan@0
   493
{
nathan@0
   494
  bool r=obj->Rename(AddExt(newName,PLAYLISTEXT));
nathan@0
   495
  if(r) Set();
nathan@0
   496
  return r;
nathan@0
   497
}
nathan@0
   498
nathan@0
   499
bool cPlayList::Create(const char *newName)
nathan@0
   500
{
nathan@0
   501
  bool r=obj->Create(AddExt(newName,PLAYLISTEXT));
nathan@0
   502
  if(r) {
nathan@0
   503
    Set();
nathan@0
   504
    r=Load();
nathan@0
   505
    }
nathan@0
   506
  return r;
nathan@0
   507
}
nathan@0
   508
nathan@0
   509
bool cPlayList::Delete(void)
nathan@0
   510
{
nathan@0
   511
  return obj->Delete();
nathan@0
   512
}
nathan@0
   513
nathan@0
   514
const char *cPlayList::AddExt(const char *FileName, const char *Ext)
nathan@0
   515
{
nathan@0
   516
  free(extbuffer); extbuffer=0;
nathan@0
   517
  asprintf(&extbuffer,"%s%s",FileName,Ext);
nathan@0
   518
  return extbuffer;
nathan@0
   519
}
nathan@0
   520
nathan@0
   521
// -- cInstantPlayList ------------------------------------------------------
nathan@0
   522
nathan@0
   523
cInstantPlayList::cInstantPlayList(cFileObj *Obj)
nathan@0
   524
:cPlayList(Obj)
nathan@0
   525
{
nathan@0
   526
  if(!Obj->Name()) Obj->SetName("instant");
nathan@0
   527
}
nathan@0
   528
nathan@0
   529
bool cInstantPlayList::Load(void)
nathan@0
   530
{
nathan@0
   531
  bool res=false;
nathan@0
   532
  Clear();
nathan@0
   533
  switch(obj->Type()) {
nathan@0
   534
    case otFile:
nathan@0
   535
      d(printf("instant: file %s\n",obj->Name()))
nathan@0
   536
      if(strcasecmp(obj->Name(),basename)) {
nathan@0
   537
        d(printf("instant: detected as playlist\n"))
nathan@0
   538
        res=cPlayList::Load();
nathan@0
   539
        }
nathan@0
   540
      else {
nathan@0
   541
        Add(new cSong(obj));
nathan@0
   542
        res=true;
nathan@0
   543
        }
nathan@0
   544
      break;
nathan@0
   545
    case otDir:
nathan@0
   546
      {
nathan@0
   547
      d(printf("instant: dir %s\n",obj->Name()))
nathan@0
   548
      res=ScanDir(obj->Source(),obj->Path(),stFile,obj->Source()->Include(),excl_pl,true);
nathan@0
   549
      Sort();
nathan@0
   550
      break;
nathan@0
   551
      }
nathan@0
   552
    case otBase:
nathan@0
   553
      d(printf("instant: base\n"))
nathan@0
   554
      res=ScanDir(obj->Source(),0,stFile,obj->Source()->Include(),excl_pl,true);
nathan@0
   555
      Sort();
nathan@0
   556
      break;
nathan@0
   557
    default: break;
nathan@0
   558
    }
nathan@0
   559
  return res;
nathan@0
   560
}
nathan@0
   561
nathan@0
   562
void cInstantPlayList::DoItem(cFileSource *src, const char *subdir, const char *name)
nathan@0
   563
{
nathan@0
   564
  Add(new cSong(src,subdir,name));
nathan@0
   565
}
nathan@0
   566
nathan@0
   567
// -- cPlayLists --------------------------------------------------------------
nathan@0
   568
nathan@0
   569
bool cPlayLists::Load(cFileSource *Source)
nathan@0
   570
{
nathan@0
   571
  static const char *spec[] = { "*"PLAYLISTEXT,0 };
nathan@0
   572
  Clear();
nathan@0
   573
  bool res=ScanDir(Source,0,stFile,spec,0,false);
nathan@0
   574
  Sort();
nathan@0
   575
  return res;
nathan@0
   576
}
nathan@0
   577
nathan@0
   578
void cPlayLists::DoItem(cFileSource *src, const char *subdir, const char *name)
nathan@0
   579
{
nathan@0
   580
  Add(new cPlayList(src,subdir,name));
nathan@0
   581
}