icynames are now copied to title of streams
git-svn-id: https://svn.musicpd.org/mpd/trunk@1258 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
b4a91d574f
commit
000e053ce7
61
src/decode.c
61
src/decode.c
@ -103,8 +103,9 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
|
||||
{ \
|
||||
decodeWaitedOn = 0; \
|
||||
if(openAudioDevice(&(cb->audioFormat))<0) { \
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
|
||||
pc->erroredFile[MAXPATHLEN] = '\0'; \
|
||||
strncpy(pc->erroredUrl, pc->utf8url, \
|
||||
MAXPATHLEN); \
|
||||
pc->erroredUrl[MAXPATHLEN] = '\0'; \
|
||||
pc->error = PLAYER_ERROR_AUDIO; \
|
||||
quitDecode(pc,dc); \
|
||||
return; \
|
||||
@ -115,8 +116,8 @@ int calculateCrossFadeChunks(PlayerControl * pc, AudioFormat * af) {
|
||||
pc->channels = dc->audioFormat.channels; \
|
||||
} \
|
||||
else if(dc->state!=DECODE_STATE_START || *decode_pid <= 0) { \
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
|
||||
pc->erroredFile[MAXPATHLEN] = '\0'; \
|
||||
strncpy(pc->erroredUrl, pc->utf8url, MAXPATHLEN); \
|
||||
pc->erroredUrl[MAXPATHLEN] = '\0'; \
|
||||
pc->error = PLAYER_ERROR_FILE; \
|
||||
quitDecode(pc,dc); \
|
||||
return; \
|
||||
@ -133,8 +134,8 @@ int waitOnDecode(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
|
||||
while(decode_pid && *decode_pid>0 && dc->start) my_usleep(10000);
|
||||
|
||||
if(dc->start || dc->error!=DECODE_ERROR_NOERROR) {
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
||||
pc->erroredFile[MAXPATHLEN] = '\0';
|
||||
strncpy(pc->erroredUrl, pc->utf8url, MAXPATHLEN);
|
||||
pc->erroredUrl[MAXPATHLEN] = '\0';
|
||||
pc->error = PLAYER_ERROR_FILE;
|
||||
quitDecode(pc,dc);
|
||||
return -1;
|
||||
@ -159,7 +160,7 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
|
||||
if(decode_pid && *decode_pid>0) {
|
||||
cb->next = -1;
|
||||
if(dc->state==DECODE_STATE_STOP || dc->error ||
|
||||
strcmp(dc->file,pc->file)!=0)
|
||||
strcmp(dc->utf8url, pc->utf8url)!=0)
|
||||
{
|
||||
stopDecode(dc);
|
||||
cb->begin = 0;
|
||||
@ -209,8 +210,9 @@ int decodeSeek(PlayerControl * pc, DecoderControl * dc, OutputBuffer * cb,
|
||||
if(pause) pc->state = PLAYER_STATE_PAUSE; \
|
||||
else { \
|
||||
if(openAudioDevice(NULL)<0) { \
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN); \
|
||||
pc->erroredFile[MAXPATHLEN] = '\0'; \
|
||||
strncpy(pc->erroredUrl, pc->utf8url, \
|
||||
MAXPATHLEN); \
|
||||
pc->erroredUrl[MAXPATHLEN] = '\0'; \
|
||||
pc->error = PLAYER_ERROR_AUDIO; \
|
||||
quitDecode(pc,dc); \
|
||||
return; \
|
||||
@ -239,11 +241,22 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
||||
int ret;
|
||||
InputStream inStream;
|
||||
InputPlugin * plugin;
|
||||
char path[MAXPATHLEN+1];
|
||||
|
||||
strncpy(dc->file,pc->file,MAXPATHLEN);
|
||||
dc->file[MAXPATHLEN] = '\0';
|
||||
if(isRemoteUrl(pc->utf8url)) {
|
||||
strncpy(path, pc->utf8url, MAXPATHLEN);
|
||||
}
|
||||
else strncpy(path, rmp2amp(utf8ToFsCharset(pc->utf8url)), MAXPATHLEN);
|
||||
path[MAXPATHLEN] = '\0';
|
||||
|
||||
if(openInputStream(&inStream,dc->file) < 0) {
|
||||
dc->metadataSet = 0;
|
||||
memset(dc->metadata, 0, DECODE_METADATA_LENGTH);
|
||||
dc->title = -1;
|
||||
|
||||
strncpy(dc->utf8url, pc->utf8url, MAXPATHLEN);
|
||||
dc->utf8url[MAXPATHLEN] = '\0';
|
||||
|
||||
if(openInputStream(&inStream, path) < 0) {
|
||||
dc->error = DECODE_ERROR_FILE;
|
||||
dc->start = 0;
|
||||
dc->stop = 0;
|
||||
@ -264,11 +277,19 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(inStream.metaTitle) {
|
||||
strncpy(dc->metadata, inStream.metaTitle,
|
||||
DECODE_METADATA_LENGTH-1);
|
||||
dc->title = 0;
|
||||
dc->metadataSet = 1;
|
||||
}
|
||||
|
||||
ret = DECODE_ERROR_UNKTYPE;
|
||||
if(isRemoteUrl(pc->file)) {
|
||||
if(isRemoteUrl(pc->utf8url)) {
|
||||
plugin = getInputPluginFromMimeType(inStream.mime);
|
||||
if(plugin == NULL) {
|
||||
plugin = getInputPluginFromSuffix(getSuffix(dc->file));
|
||||
plugin = getInputPluginFromSuffix(
|
||||
getSuffix(dc->utf8url));
|
||||
}
|
||||
if(plugin && (plugin->streamTypes & INPUT_PLUGIN_STREAM_URL) &&
|
||||
plugin->streamDecodeFunc)
|
||||
@ -277,7 +298,7 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
||||
}
|
||||
}
|
||||
else {
|
||||
plugin = getInputPluginFromSuffix(getSuffix(dc->file));
|
||||
plugin = getInputPluginFromSuffix(getSuffix(dc->utf8url));
|
||||
if(plugin && (plugin->streamTypes && INPUT_PLUGIN_STREAM_FILE))
|
||||
{
|
||||
if(plugin->streamDecodeFunc) {
|
||||
@ -286,14 +307,14 @@ void decodeStart(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
||||
}
|
||||
else if(plugin->fileDecodeFunc) {
|
||||
closeInputStream(&inStream);
|
||||
ret = plugin->fileDecodeFunc(cb, dc);
|
||||
ret = plugin->fileDecodeFunc(cb, dc, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(ret<0 || ret == DECODE_ERROR_UNKTYPE) {
|
||||
strncpy(pc->erroredFile, dc->file, MAXPATHLEN);
|
||||
pc->erroredFile[MAXPATHLEN] = '\0';
|
||||
strncpy(pc->erroredUrl, dc->utf8url, MAXPATHLEN);
|
||||
pc->erroredUrl[MAXPATHLEN] = '\0';
|
||||
if(ret != DECODE_ERROR_UNKTYPE) dc->error = DECODE_ERROR_FILE;
|
||||
else {
|
||||
dc->error = DECODE_ERROR_UNKTYPE;
|
||||
@ -334,8 +355,8 @@ int decoderInit(PlayerControl * pc, OutputBuffer * cb, DecoderControl * dc) {
|
||||
}
|
||||
else if(pid<0) {
|
||||
unblockSignals();
|
||||
strncpy(pc->erroredFile,pc->file,MAXPATHLEN);
|
||||
pc->erroredFile[MAXPATHLEN] = '\0';
|
||||
strncpy(pc->erroredUrl, pc->utf8url, MAXPATHLEN);
|
||||
pc->erroredUrl[MAXPATHLEN] = '\0';
|
||||
pc->error = PLAYER_ERROR_SYSTEM;
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,6 +45,8 @@
|
||||
#define DECODE_SUFFIX_MP4 5
|
||||
#define DECODE_SUFFIX_WAVE 6
|
||||
|
||||
#define DECODE_METADATA_LENGTH 4096
|
||||
|
||||
typedef struct _DecoderControl {
|
||||
volatile mpd_sint8 state;
|
||||
volatile mpd_sint8 stop;
|
||||
@ -55,9 +57,12 @@ typedef struct _DecoderControl {
|
||||
volatile mpd_sint8 seekable;
|
||||
volatile mpd_sint8 cycleLogFiles;
|
||||
volatile double seekWhere;
|
||||
char file[MAXPATHLEN+1];
|
||||
AudioFormat audioFormat;
|
||||
char utf8url[MAXPATHLEN+1];
|
||||
volatile float totalTime;
|
||||
volatile mpd_sint8 metadataSet;
|
||||
char metadata[DECODE_METADATA_LENGTH];
|
||||
volatile mpd_sint16 title;
|
||||
} DecoderControl;
|
||||
|
||||
void decodeSigHandler(int sig);
|
||||
|
@ -13,7 +13,8 @@
|
||||
typedef int (* InputPlugin_streamDecodeFunc) (OutputBuffer *, DecoderControl *,
|
||||
InputStream *);
|
||||
|
||||
typedef int (* InputPlugin_fileDecodeFunc) (OutputBuffer *, DecoderControl *);
|
||||
typedef int (* InputPlugin_fileDecodeFunc) (OutputBuffer *, DecoderControl *,
|
||||
char * path);
|
||||
|
||||
/* file should be the full path! */
|
||||
typedef MpdTag * (* InputPlugin_tagDupFunc) (char * file);
|
||||
|
@ -250,7 +250,7 @@ int getAacTotalTime(char * file) {
|
||||
}
|
||||
|
||||
|
||||
int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
int aac_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
|
||||
float time;
|
||||
float totalTime;
|
||||
faacDecHandle decoder;
|
||||
@ -270,9 +270,9 @@ int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
AacBuffer b;
|
||||
InputStream inStream;
|
||||
|
||||
if((totalTime = getAacFloatTotalTime(dc->file)) < 0) return -1;
|
||||
if((totalTime = getAacFloatTotalTime(path)) < 0) return -1;
|
||||
|
||||
if(openInputStream(&inStream,dc->file) < 0) return -1;
|
||||
if(openInputStream(&inStream, path) < 0) return -1;
|
||||
|
||||
initAacBuffer(&inStream,&b,NULL,NULL,NULL);
|
||||
|
||||
@ -328,7 +328,7 @@ int aac_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
#endif
|
||||
|
||||
if(frameInfo.error > 0) {
|
||||
ERROR("error decoding AAC file: %s\n",dc->file);
|
||||
ERROR("error decoding AAC file: %s\n", path);
|
||||
ERROR("faad2 error: %s\n",
|
||||
faacDecGetErrorMessage(frameInfo.error));
|
||||
eof = 1;
|
||||
|
@ -51,21 +51,21 @@ int getAudiofileTotalTime(char * file)
|
||||
return time;
|
||||
}
|
||||
|
||||
int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
int audiofile_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
|
||||
int fs, frame_count;
|
||||
AFfilehandle af_fp;
|
||||
int bits;
|
||||
mpd_uint16 bitRate;
|
||||
struct stat st;
|
||||
|
||||
if(stat(dc->file,&st) < 0) {
|
||||
ERROR("failed to stat: %s\n",dc->file);
|
||||
if(stat(path, &st) < 0) {
|
||||
ERROR("failed to stat: %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
af_fp = afOpenFile(dc->file,"r", NULL);
|
||||
af_fp = afOpenFile(path, "r", NULL);
|
||||
if(af_fp == AF_NULL_FILEHANDLE) {
|
||||
ERROR("failed to open: %s\n",dc->file);
|
||||
ERROR("failed to open: %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -83,7 +83,7 @@ int audiofile_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
|
||||
if (dc->audioFormat.bits != 8 && dc->audioFormat.bits != 16) {
|
||||
ERROR("Only 8 and 16-bit files are supported. %s is %i-bit\n",
|
||||
dc->file,dc->audioFormat.bits);
|
||||
path, dc->audioFormat.bits);
|
||||
afCloseFile(af_fp);
|
||||
return -1;
|
||||
}
|
||||
|
@ -45,6 +45,7 @@ typedef struct {
|
||||
DecoderControl * dc;
|
||||
InputStream inStream;
|
||||
float replayGainScale;
|
||||
char * path;
|
||||
} FlacData;
|
||||
|
||||
/* this code is based on flac123, from flac-tools */
|
||||
@ -68,7 +69,7 @@ FLAC__SeekableStreamDecoderLengthStatus flacLength(
|
||||
const FLAC__SeekableStreamDecoder *, FLAC__uint64 *, void *);
|
||||
FLAC__bool flacEOF(const FLAC__SeekableStreamDecoder *, void *);
|
||||
|
||||
int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
|
||||
int flac_decode(OutputBuffer * cb, DecoderControl *dc, char * path) {
|
||||
FLAC__SeekableStreamDecoder * flacDec;
|
||||
FlacData data;
|
||||
int status = 1;
|
||||
@ -80,9 +81,10 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
|
||||
data.cb = cb;
|
||||
data.dc = dc;
|
||||
data.replayGainScale = 1.0;
|
||||
data.path = path;
|
||||
|
||||
if(openInputStream(&(data.inStream),dc->file)<0) {
|
||||
ERROR("unable to open flac: %s\n",dc->file);
|
||||
if(openInputStream(&(data.inStream), path)<0) {
|
||||
ERROR("unable to open flac: %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -106,10 +108,10 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
|
||||
status&=FLAC__seekable_stream_decoder_set_client_data(flacDec,
|
||||
(void *)&data);
|
||||
if(!status) {
|
||||
ERROR("flac problem before init(): %s\n",dc->file);
|
||||
ERROR("flac problem before init(): %s\n", path);
|
||||
flacPrintErroredState(
|
||||
FLAC__seekable_stream_decoder_get_state(flacDec),
|
||||
dc->file);
|
||||
path);
|
||||
FLAC__seekable_stream_decoder_delete(flacDec);
|
||||
return -1;
|
||||
}
|
||||
@ -117,19 +119,19 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
|
||||
if(FLAC__seekable_stream_decoder_init(flacDec)!=
|
||||
FLAC__STREAM_DECODER_SEARCH_FOR_METADATA)
|
||||
{
|
||||
ERROR("flac problem doing init(): %s\n",dc->file);
|
||||
ERROR("flac problem doing init(): %s\n", path);
|
||||
flacPrintErroredState(
|
||||
FLAC__seekable_stream_decoder_get_state(flacDec),
|
||||
dc->file);
|
||||
path);
|
||||
FLAC__seekable_stream_decoder_delete(flacDec);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!FLAC__seekable_stream_decoder_process_until_end_of_metadata(flacDec)) {
|
||||
ERROR("flac problem reading metadata: %s\n", dc->file);
|
||||
ERROR("flac problem reading metadata: %s\n", path);
|
||||
flacPrintErroredState(
|
||||
FLAC__seekable_stream_decoder_get_state(flacDec),
|
||||
dc->file);
|
||||
path);
|
||||
FLAC__seekable_stream_decoder_delete(flacDec);
|
||||
return -1;
|
||||
}
|
||||
@ -163,7 +165,7 @@ int flac_decode(OutputBuffer * cb, DecoderControl *dc) {
|
||||
if(!dc->stop) {
|
||||
flacPrintErroredState(
|
||||
FLAC__seekable_stream_decoder_get_state(flacDec),
|
||||
dc->file);
|
||||
path);
|
||||
FLAC__seekable_stream_decoder_finish(flacDec);
|
||||
}
|
||||
FLAC__seekable_stream_decoder_delete(flacDec);
|
||||
@ -253,16 +255,16 @@ void flacError(const FLAC__SeekableStreamDecoder *dec,
|
||||
|
||||
switch(status) {
|
||||
case FLAC__STREAM_DECODER_ERROR_STATUS_LOST_SYNC:
|
||||
ERROR("flac lost sync: %s\n",data->dc->file);
|
||||
ERROR("flac lost sync: %s\n", data->path);
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_ERROR_STATUS_BAD_HEADER:
|
||||
ERROR("bad header %s\n",data->dc->file);
|
||||
ERROR("bad header %s\n", data->path);
|
||||
break;
|
||||
case FLAC__STREAM_DECODER_ERROR_STATUS_FRAME_CRC_MISMATCH:
|
||||
ERROR("crc mismatch %s\n",data->dc->file);
|
||||
ERROR("crc mismatch %s\n", data->path);
|
||||
break;
|
||||
default:
|
||||
ERROR("unknow flac error %s\n",data->dc->file);
|
||||
ERROR("unknow flac error %s\n", data->path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ uint32_t mp4_inputStreamSeekCallback(void *inStream, uint64_t position) {
|
||||
}
|
||||
|
||||
|
||||
int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
int mp4_decode(OutputBuffer * cb, DecoderControl * dc, char * path) {
|
||||
mp4ff_t * mp4fh;
|
||||
mp4ff_callback_t * mp4cb;
|
||||
int32_t track;
|
||||
@ -113,8 +113,8 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
mpd_uint16 bitRate = 0;
|
||||
InputStream inStream;
|
||||
|
||||
if(openInputStream(&inStream,dc->file) < 0) {
|
||||
ERROR("failed to open %s\n",dc->file);
|
||||
if(openInputStream(&inStream, path) < 0) {
|
||||
ERROR("failed to open %s\n", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -241,7 +241,7 @@ int mp4_decode(OutputBuffer * cb, DecoderControl * dc) {
|
||||
|
||||
if(mp4Buffer) free(mp4Buffer);
|
||||
if(frameInfo.error > 0) {
|
||||
ERROR("error decoding MP4 file: %s\n",dc->file);
|
||||
ERROR("error decoding MP4 file: %s\n", path);
|
||||
ERROR("faad2 error: %s\n",
|
||||
faacDecGetErrorMessage(frameInfo.error));
|
||||
eof = 1;
|
||||
|
@ -45,6 +45,7 @@ struct _InputStream {
|
||||
InputStreamAtEOFFunc atEOFFunc;
|
||||
InputStreamBufferFunc bufferFunc;
|
||||
void * data;
|
||||
char * metaTitle;
|
||||
};
|
||||
|
||||
/* if an error occurs for these 3 functions, then -1 is returned and errno
|
||||
|
@ -35,6 +35,7 @@ int inputStream_fileOpen(InputStream * inStream, char * filename) {
|
||||
inStream->offset = 0;
|
||||
inStream->seekable = 1;
|
||||
inStream->mime = NULL;
|
||||
inStream->metaTitle = NULL;
|
||||
|
||||
fseek(fp,0,SEEK_END);
|
||||
inStream->size = ftell(fp);
|
||||
|
@ -56,7 +56,6 @@ typedef struct _InputStreemHTTPData {
|
||||
size_t buflen;
|
||||
int timesRedirected;
|
||||
int icyMetaint;
|
||||
char * icyName;
|
||||
int prebuffer;
|
||||
} InputStreamHTTPData;
|
||||
|
||||
@ -68,7 +67,6 @@ static InputStreamHTTPData * newInputStreamHTTPData() {
|
||||
ret->port = 80;
|
||||
ret->connState = HTTP_CONN_STATE_CLOSED;
|
||||
ret->timesRedirected = 0;
|
||||
ret->icyName = NULL;
|
||||
ret->icyMetaint = 0;
|
||||
ret->prebuffer = 0;
|
||||
|
||||
@ -78,7 +76,6 @@ static InputStreamHTTPData * newInputStreamHTTPData() {
|
||||
static void freeInputStreamHTTPData(InputStreamHTTPData * data) {
|
||||
if(data->host) free(data->host);
|
||||
if(data->path) free(data->path);
|
||||
if(data->icyName) free(data->icyName);
|
||||
|
||||
free(data);
|
||||
}
|
||||
@ -374,19 +371,20 @@ static int getHTTPHello(InputStream * inStream) {
|
||||
char * temp = strstr(cur+11,"\r\n");
|
||||
if(!temp) break;
|
||||
*temp = '\0';
|
||||
if(data->icyName) free(data->icyName);
|
||||
data->icyName = strdup(cur+11);
|
||||
if(inStream->metaTitle) free(inStream->metaTitle);
|
||||
inStream->metaTitle = strdup(cur+19);
|
||||
*temp = '\r';
|
||||
DEBUG("stream icy-name: %s\n", data->icyName);
|
||||
DEBUG("stream icy-name: %s\n", inStream->metaTitle);
|
||||
}
|
||||
else if(0 == strncmp(cur, "\r\nx-audiocast-name:", 19)) {
|
||||
char * temp = strstr(cur+19,"\r\n");
|
||||
if(!temp) break;
|
||||
*temp = '\0';
|
||||
if(data->icyName) free(data->icyName);
|
||||
data->icyName = strdup(cur+19);
|
||||
if(inStream->metaTitle) free(inStream->metaTitle);
|
||||
inStream->metaTitle = strdup(cur+19);
|
||||
*temp = '\r';
|
||||
DEBUG("stream audiocast-name: %s\n", data->icyName);
|
||||
DEBUG("stream audiocast-name: %s\n",
|
||||
inStream->metaTitle);
|
||||
}
|
||||
else if(0 == strncmp(cur, "\r\nContent-Type:", 15)) {
|
||||
int incr = 15;
|
||||
@ -445,6 +443,7 @@ int inputStream_httpOpen(InputStream * inStream, char * url) {
|
||||
inStream->error = 0;
|
||||
inStream->mime = NULL;
|
||||
inStream->seekable = 0;
|
||||
inStream->metaTitle = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
55
src/player.c
55
src/player.c
@ -23,7 +23,6 @@
|
||||
#include "playlist.h"
|
||||
#include "ls.h"
|
||||
#include "listen.h"
|
||||
#include "path.h"
|
||||
#include "log.h"
|
||||
#include "utils.h"
|
||||
#include "tables.h"
|
||||
@ -179,12 +178,8 @@ int playerPlay(FILE * fp, Song * song) {
|
||||
if(song->tag) pc->fileTime = song->tag->time;
|
||||
else pc->fileTime = 0;
|
||||
|
||||
if(isRemoteUrl(song->utf8url)) {
|
||||
strncpy(pc->file, song->utf8url, MAXPATHLEN);
|
||||
}
|
||||
else strncpy(pc->file, rmp2amp(utf8ToFsCharset(song->utf8url)),
|
||||
MAXPATHLEN);
|
||||
pc->file[MAXPATHLEN] = '\0';
|
||||
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
|
||||
pc->utf8url[MAXPATHLEN] = '\0';
|
||||
|
||||
pc->play = 1;
|
||||
if(player_pid==0 && playerInit()<0) {
|
||||
@ -287,11 +282,11 @@ char * getPlayerErrorStr() {
|
||||
case PLAYER_ERROR_FILENOTFOUND:
|
||||
snprintf(error,errorlen,
|
||||
"file \"%s\" does not exist or is inaccesible",
|
||||
pc->erroredFile);
|
||||
pc->erroredUrl);
|
||||
break;
|
||||
case PLAYER_ERROR_FILE:
|
||||
snprintf(error,errorlen,"problems decoding \"%s\"",
|
||||
pc->erroredFile);
|
||||
pc->erroredUrl);
|
||||
break;
|
||||
case PLAYER_ERROR_AUDIO:
|
||||
snprintf(error,errorlen,"problems opening audio device");
|
||||
@ -301,7 +296,7 @@ char * getPlayerErrorStr() {
|
||||
break;
|
||||
case PLAYER_ERROR_UNKTYPE:
|
||||
snprintf(error,errorlen,"file type of \"%s\" is unknown",
|
||||
pc->erroredFile);
|
||||
pc->erroredUrl);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -327,12 +322,8 @@ int queueSong(Song * song) {
|
||||
PlayerControl * pc = &(getPlayerData()->playerControl);
|
||||
|
||||
if(pc->queueState==PLAYER_QUEUE_BLANK) {
|
||||
if(isRemoteUrl(song->utf8url)) {
|
||||
strncpy(pc->file, song->utf8url, MAXPATHLEN);
|
||||
}
|
||||
else strncpy(pc->file, rmp2amp(utf8ToFsCharset(song->utf8url)),
|
||||
MAXPATHLEN);
|
||||
pc->file[MAXPATHLEN] = '\0';
|
||||
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
|
||||
pc->utf8url[MAXPATHLEN] = '\0';
|
||||
|
||||
if(song->tag) pc->fileTime = song->tag->time;
|
||||
else pc->fileTime = 0;
|
||||
@ -378,7 +369,6 @@ void playerQueueUnlock() {
|
||||
|
||||
int playerSeek(FILE * fp, Song * song, float time) {
|
||||
PlayerControl * pc = &(getPlayerData()->playerControl);
|
||||
char * file;
|
||||
|
||||
if(pc->state==PLAYER_STATE_STOP) {
|
||||
myfprintf(fp,"%s player not currently playing\n",
|
||||
@ -386,14 +376,12 @@ int playerSeek(FILE * fp, Song * song, float time) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(isRemoteUrl(song->utf8url)) file = song->utf8url;
|
||||
else file = rmp2amp(utf8ToFsCharset(song->utf8url));
|
||||
if(strcmp(pc->file,file)!=0) {
|
||||
if(strcmp(pc->utf8url, song->utf8url)!=0) {
|
||||
if(song->tag) pc->fileTime = song->tag->time;
|
||||
else pc->fileTime = 0;
|
||||
|
||||
strncpy(pc->file,file,MAXPATHLEN);
|
||||
pc->file[MAXPATHLEN] = '\0';
|
||||
strncpy(pc->utf8url, song->utf8url, MAXPATHLEN);
|
||||
pc->utf8url[MAXPATHLEN] = '\0';
|
||||
}
|
||||
|
||||
if(pc->error==PLAYER_ERROR_NOERROR) {
|
||||
@ -471,4 +459,27 @@ void playerCycleLogFiles() {
|
||||
dc->cycleLogFiles = 1;
|
||||
}
|
||||
|
||||
/* this actually creates a dupe of the current metadata */
|
||||
Song * playerCurrentDecodeSong() {
|
||||
static Song * song;
|
||||
DecoderControl * dc = &(getPlayerData()->decoderControl);
|
||||
|
||||
if(dc->metadataSet && (!song || strcmp(song->utf8url, dc->utf8url))) {
|
||||
if(!song) {
|
||||
song = newNullSong();
|
||||
song->tag = newMpdTag();
|
||||
}
|
||||
if(song->utf8url) free(song->utf8url);
|
||||
song->utf8url = strdup(dc->utf8url);
|
||||
if(dc->title >= 0) {
|
||||
song->tag->title = dc->title + dc->metadata;
|
||||
}
|
||||
else song->tag->title = NULL;
|
||||
|
||||
return song;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
|
||||
|
@ -66,8 +66,8 @@ typedef struct _PlayerControl {
|
||||
volatile float totalTime;
|
||||
volatile float elapsedTime;
|
||||
volatile float fileTime;
|
||||
char file[MAXPATHLEN+1];
|
||||
char erroredFile[MAXPATHLEN+1];
|
||||
char utf8url[MAXPATHLEN+1];
|
||||
char erroredUrl[MAXPATHLEN+1];
|
||||
volatile mpd_sint8 queueState;
|
||||
volatile mpd_sint8 queueLockState;
|
||||
volatile mpd_sint8 lockQueue;
|
||||
@ -145,5 +145,7 @@ int getPlayerChannels();
|
||||
|
||||
void playerCycleLogFiles();
|
||||
|
||||
Song * playerCurrentDecodeSong();
|
||||
|
||||
#endif
|
||||
/* vim:set shiftwidth=4 tabstop=8 expandtab: */
|
||||
|
@ -108,8 +108,8 @@ void initPlayerData() {
|
||||
playerData_pd->playerControl.queueState = PLAYER_QUEUE_BLANK;
|
||||
playerData_pd->playerControl.queueLockState = PLAYER_QUEUE_UNLOCKED;
|
||||
playerData_pd->playerControl.seek = 0;
|
||||
memset(playerData_pd->playerControl.file,0,MAXPATHLEN+1);
|
||||
memset(playerData_pd->playerControl.erroredFile,0,MAXPATHLEN+1);
|
||||
memset(playerData_pd->playerControl.utf8url, 0, MAXPATHLEN+1);
|
||||
memset(playerData_pd->playerControl.erroredUrl, 0, MAXPATHLEN+1);
|
||||
playerData_pd->playerControl.crossFade = crossfade;
|
||||
playerData_pd->playerControl.softwareVolume = 1000;
|
||||
playerData_pd->playerControl.totalPlayTime = 0;
|
||||
@ -120,7 +120,11 @@ void initPlayerData() {
|
||||
playerData_pd->decoderControl.state = DECODE_STATE_STOP;
|
||||
playerData_pd->decoderControl.seek = 0;
|
||||
playerData_pd->decoderControl.error = DECODE_ERROR_NOERROR;
|
||||
memset(playerData_pd->decoderControl.file,0,MAXPATHLEN+1);
|
||||
memset(playerData_pd->decoderControl.utf8url, 0, MAXPATHLEN+1);
|
||||
memset(playerData_pd->decoderControl.metadata, 0,
|
||||
DECODE_METADATA_LENGTH);
|
||||
playerData_pd->decoderControl.title = -1;
|
||||
playerData_pd->decoderControl.metadataSet = 0;
|
||||
}
|
||||
|
||||
PlayerData * getPlayerData() {
|
||||
|
@ -734,11 +734,34 @@ int playPlaylist(FILE * fp, int song, int stopOnError) {
|
||||
return playPlaylistOrderNumber(fp,i);
|
||||
}
|
||||
|
||||
void syncCurrentPlayerDecodeMetadata() {
|
||||
long i = 0;
|
||||
Song * songPlayer = playerCurrentDecodeSong();
|
||||
Song * song;
|
||||
|
||||
if(!songPlayer) return;
|
||||
|
||||
for(i=0; i<playlist.length; i++) {
|
||||
song = playlist.songs[i];
|
||||
|
||||
if(song->type == SONG_TYPE_URL &&
|
||||
0 == strcmp(song->utf8url,
|
||||
songPlayer->utf8url))
|
||||
{
|
||||
if(song->tag) freeMpdTag(song->tag);
|
||||
song->tag = mpdTagDup(songPlayer->tag);
|
||||
incrPlaylistVersion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void syncPlayerAndPlaylist() {
|
||||
if(playlist_state!=PLAYLIST_STATE_PLAY) return;
|
||||
|
||||
if(getPlayerState()==PLAYER_STATE_STOP) playPlaylistIfPlayerStopped();
|
||||
else syncPlaylistWithQueue(!playlist_queueError);
|
||||
|
||||
syncCurrentPlayerDecodeMetadata();
|
||||
}
|
||||
|
||||
int currentSongInPlaylist(FILE * fp) {
|
||||
|
@ -44,6 +44,8 @@ typedef struct _Song {
|
||||
|
||||
typedef List SongList;
|
||||
|
||||
Song * newNullSong();
|
||||
|
||||
Song * newSong(char * utf8url, SONG_TYPE type);
|
||||
|
||||
void freeSong(Song *);
|
||||
|
14
src/tag.c
14
src/tag.c
@ -158,11 +158,15 @@ MpdTag * newMpdTag() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void freeMpdTag(MpdTag * tag) {
|
||||
void clearMpdTag(MpdTag * tag) {
|
||||
if(tag->artist) free(tag->artist);
|
||||
if(tag->album) free(tag->album);
|
||||
if(tag->title) free(tag->title);
|
||||
if(tag->track) free(tag->track);
|
||||
}
|
||||
|
||||
void freeMpdTag(MpdTag * tag) {
|
||||
clearMpdTag(tag);
|
||||
free(tag);
|
||||
}
|
||||
|
||||
@ -171,10 +175,10 @@ MpdTag * mpdTagDup(MpdTag * tag) {
|
||||
|
||||
if(tag) {
|
||||
ret = newMpdTag();
|
||||
ret->artist = strdup(tag->artist);
|
||||
ret->album = strdup(tag->album);
|
||||
ret->title = strdup(tag->title);
|
||||
ret->track = strdup(tag->track);
|
||||
if(tag->artist) ret->artist = strdup(tag->artist);
|
||||
if(tag->album) ret->album = strdup(tag->album);
|
||||
if(tag->title) ret->title = strdup(tag->title);
|
||||
if(tag->track) ret->track = strdup(tag->track);
|
||||
ret->time = tag->time;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user