コード例 #1
0
ファイル: play.c プロジェクト: iosadchii/shell-fm
int playback(FILE * streamfd, int pipefd) {
	killed = 0;
	signal(SIGUSR1, sighand);

#ifndef EXTERN_ONLY
	if(!haskey(& rc, "extern")) {
		const char * freetrack = NULL;

		struct stream data;
		struct mad_decoder dec;

#ifdef LIBAO
		static int ao_initialized = 0;

		if(!ao_initialized) {
			ao_initialize();
			ao_initialized = !0;
		}
#else
		unsigned arg;
		int fd;
#endif

		memset(& data, 0, sizeof(struct stream));

		/*
			Check if there's a stream timeout configured and set it up for timed
			reads later.
		*/
		data.timeout = -1;
		if(haskey(& rc, "stream-timeout")) {
			const char * timeout = value(& rc, "stream-timeout");
			data.timeout = atoi(timeout);

			if(data.timeout <= 0) {
				if(data.timeout < 0)
					fputs("Invalid stream-timeout.\n", stderr);

				data.timeout = -1;
			}
		}


		data.streamfd = streamfd;
		data.parent = getppid();
		data.pipefd = pipefd;
		fcntl(pipefd, F_SETFL, O_NONBLOCK);

#ifdef LIBAO
		data.driver_id = ao_default_driver_id();

		if(-1 == data.driver_id) {
			fputs("Unable to find any usable output device!\n", stderr);
			return 0;
		}

		data.fmt.bits = 16;
		data.fmt.rate = 44100;
		data.fmt.channels = 2;
		data.fmt.byte_format = AO_FMT_NATIVE;
		data.device = ao_open_live(data.driver_id,&data.fmt,NULL);

		if(NULL == data.device) {
			fprintf(stderr, "Unable to open device. %s.\n", strerror(errno));
			return 0;
		}
#else
		data.audiofd = fd = open(value(& rc, "device"), O_WRONLY);

		if(-1 == data.audiofd) {
			fprintf(
					stderr, "Couldn't open %s! %s.\n",
					value(& rc, "device"), strerror(errno)
			);
			return 0;
		}

		arg = 16; /* 16 bits */
		ioctl(data.audiofd, SOUND_PCM_WRITE_BITS, & arg);
#endif

		freetrack = value(& track, "freeTrackURL");

		if(haskey(& rc, "download")) {
			char * dnam;
			int rv;

			data.finpath = strdup(meta(value(& rc, "download"), M_RELAXPATH, & track));
			assert(data.finpath != NULL);

			data.tmppath = strjoin("", data.finpath, ".streaming", NULL);
			assert(data.tmppath != NULL);

			dnam = strdup(data.tmppath);
			rv = dnam ? mkpath(dirname(dnam)) : -1;
			free(dnam);

			if(access(data.tmppath, R_OK) == -1) {
				data.dump = (rv == 0) ? fopen(data.tmppath, "w") : NULL;

				if(!data.dump)
					fprintf(stderr, "Can't write download to %s.\n", data.tmppath);
			}
			else {
				data.dump = NULL;
			}
		}

		mad_decoder_init(& dec, & data, input, NULL, NULL, output, NULL, NULL);
		mad_decoder_run(& dec, MAD_DECODER_MODE_SYNC);
#ifndef LIBAO
		close(fd);
#endif
		mad_decoder_finish(& dec);

		if(data.dump) {
			fclose(data.dump);

			if(killed) {
				unlink(data.tmppath);
			} else {
				int rv;
#ifdef TAGLIB
				TagLib_File *tagme = taglib_file_new_type(data.tmppath, TagLib_File_MPEG);
				if(tagme != NULL) {
					TagLib_Tag *tag = taglib_file_tag(tagme);
					taglib_tag_set_title(tag, value(&track, "title"));
					taglib_tag_set_artist(tag, value(&track, "creator"));
					taglib_tag_set_album(tag, value(&track, "album"));
					taglib_file_save(tagme);
					taglib_file_free(tagme);
				}
#endif
				if(haskey(& rc, "pp-cmd")) {
					const char *ppcmd = value(& rc, "pp-cmd");
					size_t ppcmdlen = strlen(ppcmd);
					char *path = shellescape(data.tmppath);
					assert(path != NULL);
					size_t pathlen = strlen(path);
					char *command = malloc(ppcmdlen + pathlen + 2);
					assert(command != NULL);
					memcpy(command, ppcmd, ppcmdlen);
					command[ppcmdlen] = ' ';
					memcpy(command + ppcmdlen + 1, path, pathlen);
					command[ppcmdlen + 1 + pathlen] = 0;
					run(command);
					free(path);
					free(command);
				}

				rv = rename(data.tmppath, data.finpath);
				if (rv == -1)
					fprintf(stderr, "Can't rename %s to %s\n",
							data.tmppath, data.finpath);
			}

			free(data.tmppath);
			free(data.finpath);
		}
	}
	else
#endif
	{
		pid_t ppid = getppid(), cpid = 0;
		const char * cmd = meta(value(& rc, "extern"), M_SHELLESC, & track);
		FILE * ext = openpipe(cmd, & cpid);
		unsigned char * buf;

		if(!ext) {
			fprintf(stderr, "Failed to execute external player (%s). %s.\n",
					cmd, strerror(errno));
			return 0;
		}

		if(!(buf = calloc(BUFSIZE + 1, sizeof(unsigned char)))) {
			fputs("Couldn't allocate enough memory for input buffer.\n", stderr);
			fclose(ext);
			return 0;
		}

		while(!feof(streamfd)) {
			signed nbyte = fread(buf, sizeof(unsigned char), BUFSIZE, streamfd);

			if(nbyte > 0) {
				fwrite(buf, sizeof(unsigned char), nbyte, ext);
				fflush(ext);
			}

			if(kill(ppid, 0) == -1 && errno == ESRCH)
				break;

			if(killed)
				break;
		}

		free(buf);
		fclose(ext);

		waitpid(cpid, NULL, 0);
	}

	return !0;
}
コード例 #2
0
static int get_track_info(char *fullPath, 
                          mps_library_track_info_t *track_info)
{
  int rv = MPS_LIBRARYDBD_SUCCESS;

  TagLib_File *tagLibFile;
  TagLib_Tag *tagLibTag;
  TagLib_File_Type tagLibType;
  mps_library_element_type_t mpsFileType; 
  const TagLib_AudioProperties *tagLibProp;
  char *tmpString;

  MPS_DBG_PRINT("Entering %s(0x%08x)\n", __func__, (unsigned int) track_info);

  taglib_set_strings_unicode(true);

  mpsFileType = track_info->file_type;

  tagLibType = (mpsFileType==MPS_LIBRARY_MP3_FILE?TagLib_File_MPEG:
                mpsFileType==MPS_LIBRARY_FLAC_FILE?TagLib_File_FLAC:
                mpsFileType==MPS_LIBRARY_OGG_FILE?TagLib_File_OggVorbis:
                mpsFileType==MPS_LIBRARY_AAC_FILE?TagLib_File_MP4:
                mpsFileType==MPS_LIBRARY_APPLE_LOSSLESS_FILE?TagLib_File_MP4:
                mpsFileType==MPS_LIBRARY_WMA_FILE?TagLib_File_ASF:
                mpsFileType==MPS_LIBRARY_AIF_FILE?TagLib_File_AIFF:
                mpsFileType==MPS_LIBRARY_WAV_FILE?TagLib_File_WAV:
                0);

  tagLibFile = taglib_file_new_type(fullPath, tagLibType);

  if(tagLibFile == NULL) {
    MPS_DBG_PRINT("Call to taglib_file_new(%s) failed.\n", fullPath);
    rv = MPS_LIBRARYDBD_FAILURE;
    goto ERR_OUT;
  }
  
  tagLibTag = taglib_file_tag(tagLibFile);
  tagLibProp = taglib_file_audioproperties(tagLibFile);

  /* TODO: need to go one step further to determine whether a file with
     an "m4a", etc. header is actually an apple lossless */
  track_info->file_type = mpsFileType;

  tmpString = taglib_tag_title(tagLibTag);
  if (tmpString != NULL) {
    copy_string_without_edge_whitespace(track_info->title, 
                                        tmpString, 
                                        MPS_MAX_TRACK_INFO_FIELD_LENGTH);
    MPS_DBG_PRINT("Copied \"%s\" into track_title->title\n", track_info->title);
  }

  tmpString = taglib_tag_album(tagLibTag);
  if (tmpString != NULL) {
    copy_string_without_edge_whitespace(track_info->album, 
                                        tmpString, 
                                        MPS_MAX_TRACK_INFO_FIELD_LENGTH);
    MPS_DBG_PRINT("Copied \"%s\" into track_title->album\n", track_info->album);
  }

  tmpString = taglib_tag_artist(tagLibTag);
  if (tmpString != NULL) {
    copy_string_without_edge_whitespace(track_info->artist, 
                                        tmpString, 
                                        MPS_MAX_TRACK_INFO_FIELD_LENGTH);
    MPS_DBG_PRINT("Copied \"%s\" into track_title->artist\n", track_info->artist);
  }

  track_info->year = taglib_tag_year(tagLibTag);
  MPS_DBG_PRINT("Copied \"%d\" into track_title->year\n", track_info->year);

  tmpString = taglib_tag_genre(tagLibTag);
  if (tmpString != NULL) {
    copy_string_without_edge_whitespace(track_info->genre, 
                                        tmpString, 
                                        MPS_MAX_TRACK_INFO_FIELD_LENGTH);
    MPS_DBG_PRINT("Copied \"%s\" into track_title->genre\n", track_info->genre);
  }

  track_info->ordinal_track_number = taglib_tag_track(tagLibTag);
  MPS_DBG_PRINT("Copied \"%d\" into track_title->ordinal_track_number\n", 
                track_info->ordinal_track_number);


  if (tagLibProp != NULL) {
    MPS_DBG_PRINT("Setting bitrate, etc.\n");
    track_info->bitrate = 
      taglib_audioproperties_bitrate(tagLibProp);

    track_info->sampling_rate = 
      taglib_audioproperties_samplerate(tagLibProp);

    track_info->channel_mode = 
      (taglib_audioproperties_channels(tagLibProp) < 2 ?
       MPS_CHANNEL_MODE_MONO:
       MPS_CHANNEL_MODE_STEREO);

    track_info->vbr_mode = MPS_VBR_MODE_UNKNOWN;
    
    track_info->time_length = 
      taglib_audioproperties_length(tagLibProp);
      
#if 0    
    track_info->channel_mode = 
      ((finfo.mode==MPG123_M_STEREO)?MPS_CHANNEL_MODE_STEREO:
       ((finfo.mode==MPG123_M_JOINT)?MPS_CHANNEL_MODE_JOINT_STEREO:
        ((finfo.mode==MPG123_M_DUAL)?MPS_CHANNEL_MODE_DUAL_CHANNEL:
         ((finfo.mode==MPG123_M_MONO)?MPS_CHANNEL_MODE_MONO:
          MPS_CHANNEL_MODE_UNKNOWN))));
    
    track_info->vbr_mode = 
      ((finfo.vbr==MPG123_CBR)?MPS_VBR_MODE_CONSTANT:
       ((finfo.vbr==MPG123_VBR)?MPS_VBR_MODE_VARIABLE:
        ((finfo.vbr==MPG123_ABR)?MPS_VBR_MODE_AVERAGE:
         MPS_VBR_MODE_UNKNOWN)));
    
    if (track_info->sampling_rate > 0) {
      total_samples = mpg123_length_64(m);
      track_info->time_length = total_samples/track_info->sampling_rate;
    }
#endif
  }
  else {
    MPS_LOG("taglib_file_audioproperties() returned NULL");
  }

 ERR_OUT:
  taglib_tag_free_strings();
  taglib_file_free(tagLibFile);

  MPS_DBG_PRINT("Leaving %s() - return value %d\n", __func__, rv);

  return rv;
}
コード例 #3
0
ファイル: mp4_tag.c プロジェクト: EQ4/easytag
/*
 * Mp4_Tag_Read_File_Tag:
 *
 * Read tag data into an Mp4 file.
 *
 * Note:
 *  - for string fields, //if field is found but contains no info (strlen(str)==0), we don't read it
 *  - for track numbers, if they are zero, then we don't read it
 */
gboolean Mp4tag_Read_File_Tag (gchar *filename, File_Tag *FileTag)
{
    FILE   *file;
    TagLib_File *mp4file;
    TagLib_Tag *tag;
    guint track;

    if (!filename || !FileTag)
        return FALSE;

    if ( (file=fopen(filename,"r"))==NULL )
    {
        gchar *filename_utf8 = filename_to_display(filename);
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
        g_free(filename_utf8);
        return FALSE;
    }
    fclose(file); // We close it cause mp4 opens/closes file itself

    /* Get data from tag */
    mp4file = taglib_file_new_type(filename,TagLib_File_MP4);
    if (mp4file == NULL)
    {
        gchar *filename_utf8 = filename_to_display(filename);
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,_("MP4 format invalid"));
        g_free(filename_utf8);
        return FALSE;
    }

    /* TODO Add error detection */
    tag = taglib_file_tag(mp4file);

    /*********
     * Title *
     *********/
    FileTag->title = g_strdup(taglib_tag_title(tag));

    /**********
     * Artist *
     **********/
    FileTag->artist = g_strdup(taglib_tag_artist(tag));

    /*********
     * Album *
     *********/
    FileTag->album = g_strdup(taglib_tag_album(tag));

    /****************
     * Album Artist *
     ****************/
    /* TODO: No album artist or disc number support in the TagLib C API! */

    /********
     * Year *
     ********/
    FileTag->year = g_strdup_printf("%u", taglib_tag_year(tag));

    /*************************
     * Track and Total Track *
     *************************/
    track = taglib_tag_track(tag);

    if (track != 0)
        FileTag->track = NUMBER_TRACK_FORMATED ? g_strdup_printf("%.*d",NUMBER_TRACK_FORMATED_SPIN_BUTTON,(gint)track) : g_strdup_printf("%d",(gint)track);
    /* TODO: No total track support in the TagLib C API! */

    /*********
     * Genre *
     *********/
    FileTag->genre = g_strdup(taglib_tag_genre(tag));

    /***********
     * Comment *
     ***********/
    FileTag->comment = g_strdup(taglib_tag_comment(tag));

    /**********************
     * Composer or Writer *
     **********************/
    /* TODO: No composer support in the TagLib C API! */

    /*****************
     * Encoding Tool *
     *****************/
    /* TODO: No encode_by support in the TagLib C API! */

    /***********
     * Picture *
     ***********/
    /* TODO: No encode_by support in the TagLib C API! */

    /* Free allocated data */
    taglib_tag_free_strings();
    taglib_file_free(mp4file);

    return TRUE;
}
コード例 #4
0
ファイル: scan-mpc.c プロジェクト: AntDok/forked-daapd
/**
 * scan a musepack file for metainfo.
 *
 * @param filename file to read metainfo for
 * @param pmp3 MP3FILE structure to fill
 * @returns TRUE if file should be added to DB, FALSE otherwise
 */
int scan_get_mpcinfo(char *filename, MP3FILE *pmp3) {
    TagLib_File *file;
    TagLib_Tag *tag;
    const TagLib_AudioProperties *properties;
    char *val;
    int len;
    unsigned int i;

    /* open file with taglib */
    if ((file = taglib_file_new_type(filename, TagLib_File_MPC)) == NULL) {
        DPRINTF(E_WARN,L_SCAN,"Could not open %s with taglib\n", filename);
        return FALSE;
    }

    /* retrieve all tags */
    if ((tag = taglib_file_tag(file)) == NULL) {
        DPRINTF(E_WARN,L_SCAN,"Could not retrieve tags of %s\n", filename);
        taglib_file_free(file);

        return FALSE;
    }

    /* fill the MP3FILE structure with the tags */
    if ((val = taglib_tag_title(tag)) != NULL) {
        len = strlen(val);
        if ((pmp3->title = calloc(len + 1, 1)) != NULL)
            strncpy(pmp3->title, val, len);
        taglib_tag_free_strings();
    }
    if ((val = taglib_tag_artist(tag)) != NULL) {
        len = strlen(val);
        if ((pmp3->artist = calloc(len + 1, 1)) != NULL)
            strncpy(pmp3->artist, val, len);
        taglib_tag_free_strings();
    }
    if ((val = taglib_tag_album(tag)) != NULL) {
        len = strlen(val);
        if ((pmp3->album = calloc(len + 1, 1)) != NULL)
            strncpy(pmp3->album, val, len);
        taglib_tag_free_strings();
    }
    if ((val = taglib_tag_comment(tag)) != NULL) {
        len = strlen(val);
        if ((pmp3->comment = calloc(len + 1, 1)) != NULL)
            strncpy(pmp3->comment, val, len);
        taglib_tag_free_strings();
    }
    if ((val = taglib_tag_genre(tag)) != NULL) {
        len = strlen(val);
        if ((pmp3->genre = calloc(len + 1, 1)) != NULL)
            strncpy(pmp3->genre, val, len);
        taglib_tag_free_strings();
    }

    if ((i = taglib_tag_year(tag)) != 0)
        pmp3->year = i;
    if ((i = taglib_tag_track(tag)) != 0)
        pmp3->track = i;

    /* load the properties (like bitrate) from the file */
    if ((properties = taglib_file_audioproperties(file)) == NULL) {
        DPRINTF(E_WARN,L_SCAN,"Could not retrieve properties of %s\n", filename);
        return FALSE;
    }

    /* fill the properties in the MP3FILE structure */
    pmp3->song_length = taglib_audioproperties_length(properties) * 1000;
    pmp3->bitrate = taglib_audioproperties_bitrate(properties);
    pmp3->samplerate = taglib_audioproperties_samplerate(properties);

    taglib_file_free(file);

    return TRUE;
}
コード例 #5
0
ファイル: mp4_tag.c プロジェクト: EQ4/easytag
/*
 * Mp4_Tag_Write_File_Tag:
 *
 * Write tag data into an Mp4 file.
 *
 * Note:
 *  - for track numbers, we write 0's if one or the other is blank
 */
gboolean Mp4tag_Write_File_Tag (ET_File *ETFile)
{
    File_Tag *FileTag;
    gchar    *filename;
    gchar    *filename_utf8;
    FILE     *file;
    TagLib_File *mp4file = NULL;
    TagLib_Tag *tag;
    gint error = 0;

    if (!ETFile || !ETFile->FileTag)
        return FALSE;

    FileTag = (File_Tag *)ETFile->FileTag->data;
    filename      = ((File_Name *)ETFile->FileNameCur->data)->value;
    filename_utf8 = ((File_Name *)ETFile->FileNameCur->data)->value_utf8;

    /* Test to know if we can write into the file */
    if ( (file=fopen(filename,"r+"))==NULL )
    {
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,g_strerror(errno));
        return FALSE;
    }
    fclose(file);

    /* Open file for writing */
    mp4file = taglib_file_new_type(filename, TagLib_File_MP4);
    if (mp4file == NULL)
    {
        Log_Print(LOG_ERROR,_("ERROR while opening file: '%s' (%s)."),filename_utf8,_("MP4 format invalid"));
        return FALSE;
    }

    tag = taglib_file_tag(mp4file);

    /*********
     * Title *
     *********/
    if (FileTag->title && g_utf8_strlen(FileTag->title, -1) > 0)
    {
        taglib_tag_set_title(tag, FileTag->title);
    }else
    {
        taglib_tag_set_title(tag,"");
    }

    /**********
     * Artist *
     **********/
    if (FileTag->artist && g_utf8_strlen(FileTag->artist, -1) > 0)
    {
        taglib_tag_set_artist(tag,FileTag->artist);
    }else
    {
        taglib_tag_set_artist(tag,"");
    }

    /*********
     * Album *
     *********/
    if (FileTag->album && g_utf8_strlen(FileTag->album, -1) > 0)
    {
        taglib_tag_set_album(tag,FileTag->album);
    }else
    {
        taglib_tag_set_album(tag,"");
    }


    /********
     * Year *
     ********/
    if (FileTag->year && g_utf8_strlen(FileTag->year, -1) > 0)
    {
        taglib_tag_set_year(tag,atoi(FileTag->year));
    }else
    {
        taglib_tag_set_year(tag,0);
    }

    /*************************
     * Track and Total Track *
     *************************/
    if ( FileTag->track && g_utf8_strlen(FileTag->track, -1) > 0 )
    {
        taglib_tag_set_track(tag,atoi(FileTag->track));
    }else
    {
        taglib_tag_set_track(tag,0);
    }

    /*********
     * Genre *
     *********/
    if (FileTag->genre && g_utf8_strlen(FileTag->genre, -1) > 0 )
    {
        taglib_tag_set_genre(tag,FileTag->genre);
    }else
    {
        taglib_tag_set_genre(tag,"");
    }

    /***********
     * Comment *
     ***********/
    if (FileTag->comment && g_utf8_strlen(FileTag->comment, -1) > 0)
    {
        taglib_tag_set_comment(tag,FileTag->comment);
    }else
    {
        taglib_tag_set_comment(tag,"");
    }

    /**********************
     * Composer or Writer *
     **********************/

    /*****************
     * Encoding Tool *
     *****************/

    /***********
     * Picture *
     ***********/

    taglib_file_save(mp4file);
    taglib_file_free(mp4file);

    if (error) return FALSE;
    else       return TRUE;
}