1
0
mirror of https://gitlab.xiph.org/xiph/ezstream.git synced 2024-09-15 04:08:07 -04:00

Include the total playing time of a song in the "real-time" output, if TagLib

supplies it.


git-svn-id: https://svn.xiph.org/trunk/ezstream@12711 0101bb08-14d6-0310-b084-bc0e0c8e3800
This commit is contained in:
moritz 2007-03-10 21:18:21 +00:00
parent 5125437d3f
commit 6eb5d8f557
4 changed files with 77 additions and 20 deletions

2
NEWS
View File

@ -19,6 +19,8 @@ Changes in 0.4.0, (SVN trunk):
* various: * various:
- [ADD] Allow ezstream to use TagLib for reading metadata from media - [ADD] Allow ezstream to use TagLib for reading metadata from media
files. TagLib (libtag_c) is now an optional dependency. files. TagLib (libtag_c) is now an optional dependency.
- [ADD] When built with TagLib support, include the song length in the
"real-time" information line, if available.
- [ADD] New <metadata_progname> configuration option, which causes - [ADD] New <metadata_progname> configuration option, which causes
metadata to be read from the output of an external program or metadata to be read from the output of an external program or
script. script.

View File

@ -110,14 +110,18 @@ typedef struct tag_ID3Tag {
} ID3Tag; } ID3Tag;
int urlParse(const char *, char **, int *, char **); int urlParse(const char *, char **, int *, char **);
void replaceString(const char *, char *, size_t, const char *, const char *); void replaceString(const char *, char *, size_t, const char *,
const char *);
char * buildCommandString(const char *, const char *, metadata_t *); char * buildCommandString(const char *, const char *, metadata_t *);
char * getMetadataString(const char *, metadata_t *); char * getMetadataString(const char *, metadata_t *);
metadata_t * getMetadata(const char *); metadata_t * getMetadata(const char *);
int setMetadata(shout_t *, metadata_t *, char **); int setMetadata(shout_t *, metadata_t *, char **);
FILE * openResource(shout_t *, const char *, int *, char **, int *); FILE * openResource(shout_t *, const char *, int *, char **, int *,
int *);
int reconnectServer(shout_t *, int); int reconnectServer(shout_t *, int);
int sendStream(shout_t *, FILE *, const char *, int, void *); const char * getTimeString(int);
int sendStream(shout_t *, FILE *, const char *, int, const char *,
void *);
int streamFile(shout_t *, const char *); int streamFile(shout_t *, const char *);
int streamPlaylist(shout_t *, const char *); int streamPlaylist(shout_t *, const char *);
char * getProgname(const char *); char * getProgname(const char *);
@ -505,7 +509,7 @@ setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
FILE * FILE *
openResource(shout_t *shout, const char *fileName, int *popenFlag, openResource(shout_t *shout, const char *fileName, int *popenFlag,
char **metaCopy, int *isStdin) char **metaCopy, int *isStdin, int *songLen)
{ {
FILE *filep = NULL; FILE *filep = NULL;
char extension[25]; char extension[25];
@ -561,6 +565,8 @@ openResource(shout_t *shout, const char *fileName, int *popenFlag,
} }
if (metaCopy != NULL) if (metaCopy != NULL)
*metaCopy = metadata_assemble_string(mdata); *metaCopy = metadata_assemble_string(mdata);
if (songLen != NULL)
*songLen = metadata_get_length(mdata);
*popenFlag = 0; *popenFlag = 0;
if (pezConfig->reencode) { if (pezConfig->reencode) {
@ -661,9 +667,28 @@ reconnectServer(shout_t *shout, int closeConn)
return (0); return (0);
} }
const char *
getTimeString(int seconds)
{
static char str[20];
int secs, mins, hours;
if (seconds < 0)
return (NULL);
secs = seconds;
hours = secs / 3600;
secs %= 3600;
mins = secs / 60;
secs %= 60;
snprintf(str, sizeof(str), "%uh%02um%02us", hours, mins, secs);
return ((const char *)str);
}
int int
sendStream(shout_t *shout, FILE *filepstream, const char *fileName, sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
int isStdin, void *tv) int isStdin, const char *songLenStr, void *tv)
{ {
unsigned char buff[4096]; unsigned char buff[4096];
size_t read, total, oldTotal; size_t read, total, oldTotal;
@ -728,7 +753,6 @@ sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY
struct timeval tv; struct timeval tv;
double oldTime, newTime; double oldTime, newTime;
unsigned int hrs, mins, secs;
#endif /* HAVE_GETTIMEOFDAY */ #endif /* HAVE_GETTIMEOFDAY */
if (!isStdin && playlistMode) { if (!isStdin && playlistMode) {
@ -749,18 +773,19 @@ sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
newTime = (double)tv.tv_sec newTime = (double)tv.tv_sec
+ (double)tv.tv_usec / 1000000.0; + (double)tv.tv_usec / 1000000.0;
secs = tv.tv_sec - startTime->tv_sec; if (songLenStr == NULL)
hrs = secs / 3600; printf(" [ %s]",
secs %= 3600; getTimeString(tv.tv_sec - startTime->tv_sec));
mins = secs / 60; else
secs %= 60; printf(" [ %s/%s]",
getTimeString(tv.tv_sec - startTime->tv_sec),
songLenStr);
if (newTime - oldTime >= 1.0) { if (newTime - oldTime >= 1.0) {
kbps = (((double)(total - oldTotal) / (newTime - oldTime)) * 8.0) / 1000.0; kbps = (((double)(total - oldTotal) / (newTime - oldTime)) * 8.0) / 1000.0;
timeStamp.tv_sec = tv.tv_sec; timeStamp.tv_sec = tv.tv_sec;
timeStamp.tv_usec = tv.tv_usec; timeStamp.tv_usec = tv.tv_usec;
oldTotal = total; oldTotal = total;
} }
printf(" [ %uh%02um%02us]", hrs, mins, secs);
if (kbps < 0) if (kbps < 0)
printf(" "); printf(" ");
else else
@ -788,15 +813,15 @@ streamFile(shout_t *shout, const char *fileName)
{ {
FILE *filepstream = NULL; FILE *filepstream = NULL;
int popenFlag = 0; int popenFlag = 0;
char *metaData = NULL; char *metaData = NULL, *songLenStr = NULL;
int isStdin = 0; int isStdin = 0;
int ret, retval = 0; int ret, retval = 0, songLen;
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY
struct timeval startTime; struct timeval startTime;
#endif #endif
if ((filepstream = openResource(shout, fileName, &popenFlag, if ((filepstream = openResource(shout, fileName, &popenFlag,
&metaData, &isStdin)) &metaData, &isStdin, &songLen))
== NULL) { == NULL) {
return (retval); return (retval);
} }
@ -811,13 +836,15 @@ streamFile(shout_t *shout, const char *fileName)
} }
#ifdef HAVE_GETTIMEOFDAY #ifdef HAVE_GETTIMEOFDAY
if (songLen >= 0)
songLenStr = xstrdup(getTimeString(songLen));
gettimeofday(&startTime, NULL); gettimeofday(&startTime, NULL);
do { do {
ret = sendStream(shout, filepstream, fileName, isStdin, ret = sendStream(shout, filepstream, fileName, isStdin,
(void *)&startTime); songLenStr, (void *)&startTime);
#else #else
do { do {
ret = sendStream(shout, filepstream, fileName, isStdin, NULL); ret = sendStream(shout, filepstream, fileName, isStdin, NULL, NULL);
#endif #endif
if (ret != STREAM_DONE) { if (ret != STREAM_DONE) {
if ((skipTrack && rereadPlaylist) || if ((skipTrack && rereadPlaylist) ||
@ -875,6 +902,9 @@ streamFile(shout_t *shout, const char *fileName)
else else
fclose(filepstream); fclose(filepstream);
if (songLenStr != NULL)
xfree(songLenStr);
return (retval); return (retval);
} }

View File

@ -53,6 +53,7 @@ struct metadata {
char *string; char *string;
char *artist; char *artist;
char *title; char *title;
int songLen;
int program; int program;
}; };
@ -81,6 +82,7 @@ metadata_create(const char *filename)
md = xcalloc(1, sizeof(metadata_t)); md = xcalloc(1, sizeof(metadata_t));
md->filename = xstrdup(filename); md->filename = xstrdup(filename);
md->songLen = -1;
return (md); return (md);
} }
@ -89,9 +91,10 @@ void
metadata_use_taglib(metadata_t *md, FILE **filep) metadata_use_taglib(metadata_t *md, FILE **filep)
#ifdef HAVE_TAGLIB #ifdef HAVE_TAGLIB
{ {
TagLib_File *tf; TagLib_File *tf;
TagLib_Tag *tt; TagLib_Tag *tt;
char *str; TagLib_AudioProperties *ta;
char *str;
if (md == NULL || md->filename == NULL) { if (md == NULL || md->filename == NULL) {
printf("%s: metadata_use_taglib(): Internal error: Bad arguments\n", printf("%s: metadata_use_taglib(): Internal error: Bad arguments\n",
@ -113,7 +116,9 @@ metadata_use_taglib(metadata_t *md, FILE **filep)
md->string = metadata_get_name(md->filename); md->string = metadata_get_name(md->filename);
return; return;
} }
tt = taglib_file_tag(tf); tt = taglib_file_tag(tf);
ta = taglib_file_audioproperties(tf);
str = taglib_tag_artist(tt); str = taglib_tag_artist(tt);
if (str != NULL) { if (str != NULL) {
@ -129,6 +134,8 @@ metadata_use_taglib(metadata_t *md, FILE **filep)
xfree(str); xfree(str);
} }
md->songLen = taglib_audioproperties_length(ta);
taglib_file_free(tf); taglib_file_free(tf);
} }
#else #else
@ -602,6 +609,18 @@ metadata_get_filename(metadata_t *md)
return (md->filename); return (md->filename);
} }
int
metadata_get_length(metadata_t *md)
{
if (md == NULL) {
printf("%s: metadata_get_length(): Internal error: Bad arguments\n",
__progname);
abort();
}
return (md->songLen);
}
char * char *
metadata_assemble_string(metadata_t *md) metadata_assemble_string(metadata_t *md)
{ {

View File

@ -96,6 +96,12 @@ const char * metadata_get_title(metadata_t *);
*/ */
const char * metadata_get_filename(metadata_t *); const char * metadata_get_filename(metadata_t *);
/*
* Returns the length of the song, in seconds, or -1 if the information is not
* available.
*/
int metadata_get_length(metadata_t *);
/* /*
* Allocates and returns a meaningful string based on a metadata handle's * Allocates and returns a meaningful string based on a metadata handle's
* content. The result is what metadata_get_string() defaults to if an external * content. The result is what metadata_get_string() defaults to if an external