Beispiel #1
0
/*!
 * \brief Read the albumart image from the file
 *
 * \param filename The filename for which we want to find the length.
 * \param type The type of image we want - front/back etc
 * \returns A pointer to a QImage owned by the caller or NULL if not found.
 */
QImage* MetaIOID3::getAlbumArt(QString filename, ImageType type)
{
    QImage *picture = new QImage();

    AttachedPictureFrame::Type apicType
        = AttachedPictureFrame::FrontCover;

    switch (type)
    {
        case IT_UNKNOWN :
            apicType = AttachedPictureFrame::Other;
            break;
        case IT_FRONTCOVER :
            apicType = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER :
            apicType = AttachedPictureFrame::BackCover;
            break;
        case IT_CD :
            apicType = AttachedPictureFrame::Media;
            break;
        case IT_INLAY :
            apicType = AttachedPictureFrame::LeafletPage;
            break;
        default:
            return picture;
    }

    QByteArray fname = filename.toLocal8Bit();
    TagLib::MPEG::File *mpegfile = new TagLib::MPEG::File(fname.constData());

    if (mpegfile)
    {
        if (mpegfile->isOpen()
            && !mpegfile->ID3v2Tag()->frameListMap()["APIC"].isEmpty())
        {
            TagLib::ID3v2::FrameList apicframes =
                                    mpegfile->ID3v2Tag()->frameListMap()["APIC"];

            for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
                it != apicframes.end(); ++it)
            {
                AttachedPictureFrame *frame =
                                    static_cast<AttachedPictureFrame *>(*it);
                if (frame && frame->type() == apicType)
                {
                    picture->loadFromData((const uchar *)frame->picture().data(),
                                          frame->picture().size());
                    return picture;
                }
            }
        }

        delete mpegfile;
    }

    delete picture;

    return NULL;
}
Beispiel #2
0
/*!
 * \brief Read the albumart image from the file
 *
 * \param filename The filename for which we want to find the albumart.
 * \param type The type of image we want - front/back etc
 * \returns A pointer to a QImage owned by the caller or nullptr if not found.
 */
QImage* MetaIOID3::getAlbumArt(const QString &filename, ImageType type)
{
    QImage *picture = new QImage();

    AttachedPictureFrame::Type apicType
        = AttachedPictureFrame::FrontCover;

    switch (type)
    {
        case IT_UNKNOWN :
            apicType = AttachedPictureFrame::Other;
            break;
        case IT_FRONTCOVER :
            apicType = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER :
            apicType = AttachedPictureFrame::BackCover;
            break;
        case IT_CD :
            apicType = AttachedPictureFrame::Media;
            break;
        case IT_INLAY :
            apicType = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST :
            apicType = AttachedPictureFrame::Artist;
            break;
        default:
            return picture;
    }

    if (OpenFile(filename))
    {
        TagLib::ID3v2::Tag *tag = GetID3v2Tag();
        if (tag && !tag->frameListMap()["APIC"].isEmpty())
        {
            TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"];

            for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
                it != apicframes.end(); ++it)
            {
                AttachedPictureFrame *frame =
                                    static_cast<AttachedPictureFrame *>(*it);
                if (frame && frame->type() == apicType)
                {
                    picture->loadFromData((const uchar *)frame->picture().data(),
                                         frame->picture().size());
                    return picture;
                }
            }
        }
    }

    delete picture;

    return nullptr;
}
Beispiel #3
0
/*!
 * \brief Find an APIC tag by type and optionally description
 *
 * \param tag Pointer to TagLib::ID3v2::Tag object
 * \param type Type of picture to search for
 * \param description Description of picture to search for (optional)
 * \returns Pointer to frame
 */
AttachedPictureFrame* MetaIOID3::findAPIC(TagLib::ID3v2::Tag *tag,
                                        const AttachedPictureFrame::Type &type,
                                        const String &description)
{
  TagLib::ID3v2::FrameList l = tag->frameList("APIC");
  for(TagLib::ID3v2::FrameList::Iterator it = l.begin(); it != l.end(); ++it)
  {
    AttachedPictureFrame *f = static_cast<AttachedPictureFrame *>(*it);
    if (f && f->type() == type &&
        (description.isNull() || f->description() == description))
      return f;
  }
  return nullptr;
}
Beispiel #4
0
void ID3v2::Tag::setAlbumArt(const ByteVector &v, ID3v2::AttachedPictureFrame::Type arttype, String &mimetype)
{
	if (v.isEmpty()) {
		removeFrames("APIC");
		return;
	} else {
		if (!d->frameListMap["APIC"].isEmpty()) {
			removeFrames("APIC");
		} else {
			// do nothing
		}
		AttachedPictureFrame *f = new AttachedPictureFrame("APIC");
		f->setMimeType(mimetype);
		f->setType(arttype);
		f->setPicture(v);
		addFrame(f);
	}
	return;
}
Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const
{
  Frame::Header *header = new Frame::Header(data, version);
  ByteVector frameID = header->frameID();

  // A quick sanity check -- make sure that the frameID is 4 uppercase Latin1
  // characters.  Also make sure that there is data in the frame.

  if(!frameID.size() == (version < 3 ? 3 : 4) ||
     header->frameSize() <= 0 ||
     header->frameSize() > data.size())
  {
    delete header;
    return 0;
  }

  for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) {
    if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) {
      delete header;
      return 0;
    }
  }

  // TagLib doesn't mess with encrypted frames, so just treat them
  // as unknown frames.

#if HAVE_ZLIB == 0
  if(header->compression()) {
    debug("Compressed frames are currently not supported.");
    return new UnknownFrame(data, header);
  }
#endif
  if(header->encryption()) {
    debug("Encrypted frames are currently not supported.");
    return new UnknownFrame(data, header);
  }

  if(!updateFrame(header)) {
    header->setTagAlterPreservation(true);
    return new UnknownFrame(data, header);
  }

  // updateFrame() might have updated the frame ID.

  frameID = header->frameID();

  // This is where things get necissarily nasty.  Here we determine which
  // Frame subclass (or if none is found simply an Frame) based
  // on the frame ID.  Since there are a lot of possibilities, that means
  // a lot of if blocks.

  // Text Identification (frames 4.2)

  if(frameID.startsWith("T")) {
    TextIdentificationFrame *f = frameID != "TXXX"
      ? new TextIdentificationFrame(data, header)
      : new UserTextIdentificationFrame(data, header);

    if(d->useDefaultEncoding)
      f->setTextEncoding(d->defaultEncoding);

    if(frameID == "TCON")
      updateGenre(f);

    return f;
  }

  // Comments (frames 4.10)

  if(frameID == "COMM") {
    CommentsFrame *f = new CommentsFrame(data, header);
    if(d->useDefaultEncoding)
      f->setTextEncoding(d->defaultEncoding);
    return f;
  }

  // Attached Picture (frames 4.14)

  if(frameID == "APIC") {
    AttachedPictureFrame *f = new AttachedPictureFrame(data, header);
    if(d->useDefaultEncoding)
      f->setTextEncoding(d->defaultEncoding);
    return f;
  }

  // Relative Volume Adjustment (frames 4.11)

  if(frameID == "RVA2")
    return new RelativeVolumeFrame(data, header);

  // Unique File Identifier (frames 4.1)

  if(frameID == "UFID")
    return new UniqueFileIdentifierFrame(data, header);

  // General Encapsulated Object (frames 4.15)

  if(frameID == "GEOB")
    return new GeneralEncapsulatedObjectFrame(data, header);

  return new UnknownFrame(data, header);
}
Beispiel #6
0
bool MetaIOID3::changeImageType(const QString &filename,
                                const AlbumArtImage* albumart,
                                ImageType newType)
{
    if (!albumart)
        return false;

    if (albumart->m_imageType == newType)
        return true;

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->m_imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST:
            type = AttachedPictureFrame::Artist;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    if (!OpenFile(filename, true))
        return false;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag();

    if (!tag)
        return false;

    AttachedPictureFrame *apic = findAPIC(tag, type,
                                    QStringToTString(albumart->m_description));
    if (!apic)
        return false;

    // set the new image type
    switch (newType)
    {
        case IT_FRONTCOVER:
            apic->setType(AttachedPictureFrame::FrontCover);
            break;
        case IT_BACKCOVER:
            apic->setType(AttachedPictureFrame::BackCover);
            break;
        case IT_CD:
            apic->setType(AttachedPictureFrame::Media);
            break;
        case IT_INLAY:
            apic->setType(AttachedPictureFrame::LeafletPage);
            break;
        case IT_ARTIST:
            apic->setType(AttachedPictureFrame::Artist);
            break;
        default:
            apic->setType(AttachedPictureFrame::Other);
            break;
    }

    if (!SaveFile())
        return false;

    return true;
}
Beispiel #7
0
/*!
 * \brief Write the albumart image to the file
 *
 * \param filename The music file to add the albumart
 * \param albumart The Album Art image to write
 * \returns True if successful
 *
 * \note We always save the image in JPEG format
 */
bool MetaIOID3::writeAlbumArt(const QString &filename,
                              const AlbumArtImage *albumart)
{
    if (filename.isEmpty() || !albumart)
        return false;

    // load the image into a QByteArray
    QImage image(albumart->m_filename);
    QByteArray imageData;
    QBuffer buffer(&imageData);
    buffer.open(QIODevice::WriteOnly);
    image.save(&buffer, "JPEG");

    AttachedPictureFrame::Type type = AttachedPictureFrame::Other;
    switch (albumart->m_imageType)
    {
        case IT_FRONTCOVER:
            type = AttachedPictureFrame::FrontCover;
            break;
        case IT_BACKCOVER:
            type = AttachedPictureFrame::BackCover;
            break;
        case IT_CD:
            type = AttachedPictureFrame::Media;
            break;
        case IT_INLAY:
            type = AttachedPictureFrame::LeafletPage;
            break;
        case IT_ARTIST:
            type = AttachedPictureFrame::Artist;
            break;
        default:
            type = AttachedPictureFrame::Other;
            break;
    }

    if (!OpenFile(filename, true))
        return false;

    TagLib::ID3v2::Tag *tag = GetID3v2Tag();

    if (!tag)
        return false;

    AttachedPictureFrame *apic = findAPIC(tag, type,
                                    QStringToTString(albumart->m_description));

    if (!apic)
    {
        apic = new AttachedPictureFrame();
        tag->addFrame(apic);
        apic->setType(type);
    }

    QString mimetype = "image/jpeg";

    TagLib::ByteVector bytevector;
    bytevector.setData(imageData.data(), imageData.size());

    apic->setMimeType(QStringToTString(mimetype));
    apic->setPicture(bytevector);
    apic->setDescription(QStringToTString(albumart->m_description));

    if (!SaveFile())
        return false;

    return true;
}
Beispiel #8
0
/*!
 * \brief Read the albumart images from the file
 *
 * \param tag The ID3v2 tag object in which to look for Album Art
 * \returns A QList containing a list of AlbumArtImage's
 *          with the type and description of the APIC tag.
 */
AlbumArtList MetaIOID3::readAlbumArt(TagLib::ID3v2::Tag *tag)
{
    AlbumArtList artlist;

    if (!tag->frameListMap()["APIC"].isEmpty())
    {
        TagLib::ID3v2::FrameList apicframes = tag->frameListMap()["APIC"];

        for(TagLib::ID3v2::FrameList::Iterator it = apicframes.begin();
            it != apicframes.end(); ++it)
        {

            AttachedPictureFrame *frame =
                static_cast<AttachedPictureFrame *>(*it);

            // Assume a valid image would have at least
            // 100 bytes of data (1x1 indexed gif is 35 bytes)
            if (frame->picture().size() < 100)
            {
                LOG(VB_GENERAL, LOG_NOTICE,
                    "Music Scanner - Discarding APIC frame "
                    "with size less than 100 bytes");
                continue;
            }

            AlbumArtImage *art = new AlbumArtImage();

            if (frame->description().isEmpty())
                art->m_description.clear();
            else
                art->m_description = TStringToQString(frame->description());

            art->m_embedded = true;
            art->m_hostname = gCoreContext->GetHostName();

            QString ext = getExtFromMimeType(
                                TStringToQString(frame->mimeType()).toLower());

            switch (frame->type())
            {
                case AttachedPictureFrame::FrontCover :
                    art->m_imageType = IT_FRONTCOVER;
                    art->m_filename = QString("front") + ext;
                    break;
                case AttachedPictureFrame::BackCover :
                    art->m_imageType = IT_BACKCOVER;
                    art->m_filename = QString("back") + ext;
                    break;
                case AttachedPictureFrame::Media :
                    art->m_imageType = IT_CD;
                    art->m_filename = QString("cd") + ext;
                    break;
                case AttachedPictureFrame::LeafletPage :
                    art->m_imageType = IT_INLAY;
                    art->m_filename = QString("inlay") + ext;
                    break;
                case AttachedPictureFrame::Artist :
                    art->m_imageType = IT_ARTIST;
                    art->m_filename = QString("artist") + ext;
                    break;
                case AttachedPictureFrame::Other :
                    art->m_imageType = IT_UNKNOWN;
                    art->m_filename = QString("unknown") + ext;
                    break;
                default:
                    LOG(VB_GENERAL, LOG_ERR, "Music Scanner - APIC tag found "
                                             "with unsupported type");
                    delete art;
                    continue;
            }

            artlist.append(art);
        }
    }

    return artlist;
}
int internel_decoder::get_attached_images(char* url,stream_context *streamcontext){
stream_context *sc = streamcontext;
AVInputFormat *format =  sc->pFormatCtx->iformat;

if(strcmp(format->name,"mp3") == 0){
sc->is_mp3 = 1;
}

/// If attached image of mp3 is not detected by ffmpeg then we use taglib to extract the attached image

if(strcmp(format->name,"mp3") == 0 && sc->videostream == -1){

 TagLib::MPEG::File mp3File(url);
    Tag * mp3Tag;
    FrameList listOfMp3Frames;
    AttachedPictureFrame * pictureFrame;
AVPacket packet;
//av_init_packet(&packet);

    mp3Tag= mp3File.ID3v2Tag();
    if(mp3Tag)
    {
        listOfMp3Frames = mp3Tag->frameListMap()["APIC"];
        if(!listOfMp3Frames.isEmpty())
        {
            FrameList::ConstIterator it= listOfMp3Frames.begin();
         //   for(; it != listOfMp3Frames.end() ; it++)
         //   {
pictureFrame = static_cast<AttachedPictureFrame *> (*it);
//cout <<"mime-type:"<<pictureFrame->mimeType()<<endl;
AVCodec *codec;

const char *mime_attached = pictureFrame->mimeType().toCString(false);
const CodecMime *mime = ff_id3v2_mime_tags;

 while (mime->id != AV_CODEC_ID_NONE) {
  if (!av_strncasecmp(mime->str, mime_attached, sizeof(mime_attached))) {
codec = avcodec_find_decoder(mime->id);
cout <<"mime-type:"<<mime->str<<endl;
  break;
  }
  mime++;
  }
if(mime->id != AV_CODEC_ID_NONE){


av_new_packet (&packet, pictureFrame->picture().size());
memcpy(packet.data,pictureFrame->picture().data(),pictureFrame->picture().size());
    // packet.data = (uint8_t*)pictureFrame->picture().data();
     packet.size = pictureFrame->picture().size();
     packet.flags = AV_PKT_FLAG_KEY;

pthread_mutex_lock(&sc->videolock);
sc->videobuffer.push(packet);
pthread_mutex_unlock(&sc->videolock);


sc->videoctx = avcodec_alloc_context3(NULL);

avcodec_open2(sc->videoctx,codec, NULL);
sc->attachedimage = 1;
AVFrame *frame = avcodec_alloc_frame();
int decode_ok;

int len;
while(true){
  len = avcodec_decode_video2(sc->videoctx, frame, &decode_ok, &packet);
if(decode_ok || len < 0){
break;
}
}


if(len < 0){
sc->videoctx->width = 0;
sc->videoctx->height = 0;
sc->height = 0;
sc->width = 0;
av_free(frame);
return -1;
}else{
cout <<frame->height<<" - "<<frame->width<<endl;
sc->videoctx->width = frame->width;
sc->videoctx->height = frame->height;
sc->height = frame->height;
sc->width = frame->width;
av_free(frame);
}
}else{
return -1;
}
//break;
          //  }
} else{          
return -1;
}

} else {
return -1;
}


}


return 0;
}