mirror of
https://gitlab.xiph.org/xiph/ezstream.git
synced 2024-11-03 04:17:18 -05: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:
parent
5125437d3f
commit
6eb5d8f557
2
NEWS
2
NEWS
@ -19,6 +19,8 @@ Changes in 0.4.0, (SVN trunk):
|
||||
* various:
|
||||
- [ADD] Allow ezstream to use TagLib for reading metadata from media
|
||||
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
|
||||
metadata to be read from the output of an external program or
|
||||
script.
|
||||
|
@ -110,14 +110,18 @@ typedef struct tag_ID3Tag {
|
||||
} ID3Tag;
|
||||
|
||||
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 * getMetadataString(const char *, metadata_t *);
|
||||
metadata_t * getMetadata(const 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 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 streamPlaylist(shout_t *, const char *);
|
||||
char * getProgname(const char *);
|
||||
@ -505,7 +509,7 @@ setMetadata(shout_t *shout, metadata_t *mdata, char **mdata_copy)
|
||||
|
||||
FILE *
|
||||
openResource(shout_t *shout, const char *fileName, int *popenFlag,
|
||||
char **metaCopy, int *isStdin)
|
||||
char **metaCopy, int *isStdin, int *songLen)
|
||||
{
|
||||
FILE *filep = NULL;
|
||||
char extension[25];
|
||||
@ -561,6 +565,8 @@ openResource(shout_t *shout, const char *fileName, int *popenFlag,
|
||||
}
|
||||
if (metaCopy != NULL)
|
||||
*metaCopy = metadata_assemble_string(mdata);
|
||||
if (songLen != NULL)
|
||||
*songLen = metadata_get_length(mdata);
|
||||
|
||||
*popenFlag = 0;
|
||||
if (pezConfig->reencode) {
|
||||
@ -661,9 +667,28 @@ reconnectServer(shout_t *shout, int closeConn)
|
||||
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
|
||||
sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
|
||||
int isStdin, void *tv)
|
||||
int isStdin, const char *songLenStr, void *tv)
|
||||
{
|
||||
unsigned char buff[4096];
|
||||
size_t read, total, oldTotal;
|
||||
@ -728,7 +753,6 @@ sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval tv;
|
||||
double oldTime, newTime;
|
||||
unsigned int hrs, mins, secs;
|
||||
#endif /* HAVE_GETTIMEOFDAY */
|
||||
|
||||
if (!isStdin && playlistMode) {
|
||||
@ -749,18 +773,19 @@ sendStream(shout_t *shout, FILE *filepstream, const char *fileName,
|
||||
gettimeofday(&tv, NULL);
|
||||
newTime = (double)tv.tv_sec
|
||||
+ (double)tv.tv_usec / 1000000.0;
|
||||
secs = tv.tv_sec - startTime->tv_sec;
|
||||
hrs = secs / 3600;
|
||||
secs %= 3600;
|
||||
mins = secs / 60;
|
||||
secs %= 60;
|
||||
if (songLenStr == NULL)
|
||||
printf(" [ %s]",
|
||||
getTimeString(tv.tv_sec - startTime->tv_sec));
|
||||
else
|
||||
printf(" [ %s/%s]",
|
||||
getTimeString(tv.tv_sec - startTime->tv_sec),
|
||||
songLenStr);
|
||||
if (newTime - oldTime >= 1.0) {
|
||||
kbps = (((double)(total - oldTotal) / (newTime - oldTime)) * 8.0) / 1000.0;
|
||||
timeStamp.tv_sec = tv.tv_sec;
|
||||
timeStamp.tv_usec = tv.tv_usec;
|
||||
oldTotal = total;
|
||||
}
|
||||
printf(" [ %uh%02um%02us]", hrs, mins, secs);
|
||||
if (kbps < 0)
|
||||
printf(" ");
|
||||
else
|
||||
@ -788,15 +813,15 @@ streamFile(shout_t *shout, const char *fileName)
|
||||
{
|
||||
FILE *filepstream = NULL;
|
||||
int popenFlag = 0;
|
||||
char *metaData = NULL;
|
||||
char *metaData = NULL, *songLenStr = NULL;
|
||||
int isStdin = 0;
|
||||
int ret, retval = 0;
|
||||
int ret, retval = 0, songLen;
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
struct timeval startTime;
|
||||
#endif
|
||||
|
||||
if ((filepstream = openResource(shout, fileName, &popenFlag,
|
||||
&metaData, &isStdin))
|
||||
&metaData, &isStdin, &songLen))
|
||||
== NULL) {
|
||||
return (retval);
|
||||
}
|
||||
@ -811,13 +836,15 @@ streamFile(shout_t *shout, const char *fileName)
|
||||
}
|
||||
|
||||
#ifdef HAVE_GETTIMEOFDAY
|
||||
if (songLen >= 0)
|
||||
songLenStr = xstrdup(getTimeString(songLen));
|
||||
gettimeofday(&startTime, NULL);
|
||||
do {
|
||||
ret = sendStream(shout, filepstream, fileName, isStdin,
|
||||
(void *)&startTime);
|
||||
songLenStr, (void *)&startTime);
|
||||
#else
|
||||
do {
|
||||
ret = sendStream(shout, filepstream, fileName, isStdin, NULL);
|
||||
ret = sendStream(shout, filepstream, fileName, isStdin, NULL, NULL);
|
||||
#endif
|
||||
if (ret != STREAM_DONE) {
|
||||
if ((skipTrack && rereadPlaylist) ||
|
||||
@ -875,6 +902,9 @@ streamFile(shout_t *shout, const char *fileName)
|
||||
else
|
||||
fclose(filepstream);
|
||||
|
||||
if (songLenStr != NULL)
|
||||
xfree(songLenStr);
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ struct metadata {
|
||||
char *string;
|
||||
char *artist;
|
||||
char *title;
|
||||
int songLen;
|
||||
int program;
|
||||
};
|
||||
|
||||
@ -81,6 +82,7 @@ metadata_create(const char *filename)
|
||||
|
||||
md = xcalloc(1, sizeof(metadata_t));
|
||||
md->filename = xstrdup(filename);
|
||||
md->songLen = -1;
|
||||
|
||||
return (md);
|
||||
}
|
||||
@ -89,9 +91,10 @@ void
|
||||
metadata_use_taglib(metadata_t *md, FILE **filep)
|
||||
#ifdef HAVE_TAGLIB
|
||||
{
|
||||
TagLib_File *tf;
|
||||
TagLib_Tag *tt;
|
||||
char *str;
|
||||
TagLib_File *tf;
|
||||
TagLib_Tag *tt;
|
||||
TagLib_AudioProperties *ta;
|
||||
char *str;
|
||||
|
||||
if (md == NULL || md->filename == NULL) {
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
tt = taglib_file_tag(tf);
|
||||
ta = taglib_file_audioproperties(tf);
|
||||
|
||||
str = taglib_tag_artist(tt);
|
||||
if (str != NULL) {
|
||||
@ -129,6 +134,8 @@ metadata_use_taglib(metadata_t *md, FILE **filep)
|
||||
xfree(str);
|
||||
}
|
||||
|
||||
md->songLen = taglib_audioproperties_length(ta);
|
||||
|
||||
taglib_file_free(tf);
|
||||
}
|
||||
#else
|
||||
@ -602,6 +609,18 @@ metadata_get_filename(metadata_t *md)
|
||||
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 *
|
||||
metadata_assemble_string(metadata_t *md)
|
||||
{
|
||||
|
@ -96,6 +96,12 @@ const char * metadata_get_title(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
|
||||
* content. The result is what metadata_get_string() defaults to if an external
|
||||
|
Loading…
Reference in New Issue
Block a user