Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Multimedia
Amarok
Commits
717342ed
Commit
717342ed
authored
Jan 12, 2012
by
Daniel Faust
Browse files
Support embedded covers for ogg (read only) and flac files
BUG:142579
parent
8d8404a9
Changes
4
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
717342ed
...
...
@@ -4,6 +4,7 @@ Amarok ChangeLog
Version 2.6-Beta 1
FEATURES:
* Support embedded covers for ogg (read only) and flac files. (BR 288752)
* Track meta-data can be edited in USB Mass Storage collection.
* Support for album artists in USB Mass Storage collection.
* album artist (if differs from artist), BPM, labels, last played time and
...
...
shared/tag_helpers/TagHelper.cpp
View file @
717342ed
...
...
@@ -276,7 +276,7 @@ Meta::Tag::selectHelper( const TagLib::FileRef fileref, bool forceCreation )
else
if
(
TagLib
::
FLAC
::
File
*
file
=
dynamic_cast
<
TagLib
::
FLAC
::
File
*
>
(
fileref
.
file
()
)
)
{
if
(
file
->
xiphComment
()
)
tagHelper
=
new
VorbisCommentTagHelper
(
fileref
.
tag
(),
file
->
xiphComment
(),
Amarok
::
Flac
);
tagHelper
=
new
VorbisCommentTagHelper
(
fileref
.
tag
(),
file
->
xiphComment
(),
file
,
Amarok
::
Flac
);
else
if
(
file
->
ID3v2Tag
()
)
tagHelper
=
new
ID3v2TagHelper
(
fileref
.
tag
(),
file
->
ID3v2Tag
(),
Amarok
::
Flac
);
else
if
(
file
->
ID3v1Tag
()
)
...
...
shared/tag_helpers/VorbisCommentTagHelper.cpp
View file @
717342ed
...
...
@@ -25,11 +25,42 @@
#include
"StringHelper.h"
#include
<taglib/flacpicture.h>
#ifndef UTILITIES_BUILD
#include
<QBuffer>
#endif //UTILITIES_BUILD
// Taglib added support for FLAC pictures in 1.7.0
#if (TAGLIB_MAJOR_VERSION > 1) || (TAGLIB_MAJOR_VERSION == 1 && TAGLIB_MINOR_VERSION >= 7)
# define TAGLIB_HAS_FLAC_PICTURELIST
#endif
using
namespace
Meta
::
Tag
;
VorbisCommentTagHelper
::
VorbisCommentTagHelper
(
TagLib
::
Tag
*
tag
,
TagLib
::
Ogg
::
XiphComment
*
commentsTag
,
Amarok
::
FileType
fileType
)
:
TagHelper
(
tag
,
fileType
)
,
m_tag
(
commentsTag
)
,
m_flacFile
(
0
)
{
m_fieldMap
.
insert
(
Meta
::
valAlbumArtist
,
TagLib
::
String
(
"ALBUMARTIST"
)
);
m_fieldMap
.
insert
(
Meta
::
valBpm
,
TagLib
::
String
(
"BPM"
)
);
m_fieldMap
.
insert
(
Meta
::
valCompilation
,
TagLib
::
String
(
"COMPILATION"
)
);
m_fieldMap
.
insert
(
Meta
::
valComposer
,
TagLib
::
String
(
"COMPOSER"
)
);
m_fieldMap
.
insert
(
Meta
::
valDiscNr
,
TagLib
::
String
(
"DISCNUMBER"
)
);
m_fieldMap
.
insert
(
Meta
::
valHasCover
,
TagLib
::
String
(
"COVERART"
)
);
// non-standard but frequently used
m_fieldMap
.
insert
(
Meta
::
valPlaycount
,
TagLib
::
String
(
"FMPS_PLAYCOUNT"
)
);
m_fieldMap
.
insert
(
Meta
::
valRating
,
TagLib
::
String
(
"FMPS_RATING"
)
);
m_fieldMap
.
insert
(
Meta
::
valScore
,
TagLib
::
String
(
"FMPS_RATING_AMAROK_SCORE"
)
);
m_uidFieldMap
.
insert
(
UIDAFT
,
TagLib
::
String
(
"AMAROK 2 AFTV1 - AMAROK.KDE.ORG"
)
);
m_uidFieldMap
.
insert
(
UIDMusicBrainz
,
TagLib
::
String
(
"MUSICBRAINZ_TRACKID"
)
);
}
VorbisCommentTagHelper
::
VorbisCommentTagHelper
(
TagLib
::
Tag
*
tag
,
TagLib
::
Ogg
::
XiphComment
*
commentsTag
,
TagLib
::
FLAC
::
File
*
file
,
Amarok
::
FileType
fileType
)
:
TagHelper
(
tag
,
fileType
)
,
m_tag
(
commentsTag
)
,
m_flacFile
(
file
)
{
m_fieldMap
.
insert
(
Meta
::
valAlbumArtist
,
TagLib
::
String
(
"ALBUMARTIST"
)
);
m_fieldMap
.
insert
(
Meta
::
valBpm
,
TagLib
::
String
(
"BPM"
)
);
...
...
@@ -67,6 +98,8 @@ VorbisCommentTagHelper::tags() const
data
.
insert
(
field
,
qRound
(
value
.
toFloat
()
*
10.0
)
);
else
if
(
field
==
Meta
::
valScore
)
data
.
insert
(
field
,
value
.
toFloat
()
*
100.0
);
else
if
(
field
==
Meta
::
valHasCover
)
data
.
insert
(
Meta
::
valHasCover
,
true
);
else
data
.
insert
(
field
,
value
);
}
...
...
@@ -79,6 +112,25 @@ VorbisCommentTagHelper::tags() const
}
}
#ifdef TAGLIB_HAS_FLAC_PICTURELIST
if
(
m_flacFile
)
{
const
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>
picturelist
=
m_flacFile
->
pictureList
();
for
(
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>::
ConstIterator
it
=
picturelist
.
begin
();
it
!=
picturelist
.
end
();
it
++
)
{
TagLib
::
FLAC
::
Picture
*
picture
=
*
it
;
if
(
(
picture
->
type
()
==
TagLib
::
FLAC
::
Picture
::
FrontCover
||
picture
->
type
()
==
TagLib
::
FLAC
::
Picture
::
Other
)
&&
picture
->
data
().
size
()
>
1024
)
// must be at least 1kb
{
data
.
insert
(
Meta
::
valHasCover
,
true
);
break
;
}
}
}
#endif // TAGLIB_HAS_FLAC_PICTURELIST
return
data
;
}
...
...
@@ -94,7 +146,9 @@ VorbisCommentTagHelper::setTags( const Meta::FieldHash &changes )
if
(
!
field
.
isNull
()
&&
!
field
.
isEmpty
()
)
{
if
(
key
==
Meta
::
valRating
)
if
(
key
==
Meta
::
valHasCover
)
continue
;
else
if
(
key
==
Meta
::
valRating
)
m_tag
->
addField
(
field
,
Qt4QStringToTString
(
QString
::
number
(
value
.
toFloat
()
/
10.0
)
)
);
else
if
(
key
==
Meta
::
valScore
)
m_tag
->
addField
(
field
,
Qt4QStringToTString
(
QString
::
number
(
value
.
toFloat
()
/
100.0
)
)
);
...
...
@@ -122,3 +176,156 @@ VorbisCommentTagHelper::render() const
{
return
m_tag
->
render
();
}
#ifndef UTILITIES_BUILD
bool
VorbisCommentTagHelper
::
hasEmbeddedCover
()
const
{
if
(
m_flacFile
)
{
#ifdef TAGLIB_HAS_FLAC_PICTURELIST
const
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>
picturelist
=
m_flacFile
->
pictureList
();
for
(
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>::
ConstIterator
it
=
picturelist
.
begin
();
it
!=
picturelist
.
end
();
it
++
)
{
const
TagLib
::
FLAC
::
Picture
*
picture
=
*
it
;
if
(
(
picture
->
type
()
==
TagLib
::
FLAC
::
Picture
::
FrontCover
||
picture
->
type
()
==
TagLib
::
FLAC
::
Picture
::
Other
)
&&
picture
->
data
().
size
()
>
1024
)
// must be at least 1kb
{
return
true
;
}
}
#endif // TAGLIB_HAS_FLAC_PICTURELIST
}
else
if
(
!
fieldName
(
Meta
::
valHasCover
).
isEmpty
()
)
{
TagLib
::
ByteVector
field
=
fieldName
(
Meta
::
valHasCover
).
toCString
();
return
m_tag
->
fieldListMap
().
contains
(
field
);
}
return
false
;
}
QImage
VorbisCommentTagHelper
::
embeddedCover
()
const
{
QImage
cover
;
if
(
m_flacFile
)
{
#ifdef TAGLIB_HAS_FLAC_PICTURELIST
const
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>
picturelist
=
m_flacFile
->
pictureList
();
for
(
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>::
ConstIterator
it
=
picturelist
.
begin
();
it
!=
picturelist
.
end
();
it
++
)
{
const
TagLib
::
FLAC
::
Picture
*
picture
=
*
it
;
if
(
(
picture
->
type
()
==
TagLib
::
FLAC
::
Picture
::
FrontCover
||
picture
->
type
()
==
TagLib
::
FLAC
::
Picture
::
Other
)
&&
picture
->
data
().
size
()
>
1024
)
// must be at least 1kb
{
QByteArray
image_data
(
picture
->
data
().
data
(),
picture
->
data
().
size
()
);
cover
.
loadFromData
(
image_data
);
}
}
#endif // TAGLIB_HAS_FLAC_PICTURELIST
}
else
if
(
!
fieldName
(
Meta
::
valHasCover
).
isEmpty
()
)
{
TagLib
::
ByteVector
field
=
fieldName
(
Meta
::
valHasCover
).
toCString
();
if
(
!
m_tag
->
fieldListMap
().
contains
(
field
)
)
return
cover
;
TagLib
::
StringList
coverList
=
m_tag
->
fieldListMap
()[
field
];
for
(
uint
i
=
0
;
i
<
coverList
.
size
();
i
++
)
{
QByteArray
image_data_b64
(
coverList
[
i
].
toCString
()
);
QByteArray
image_data
=
QByteArray
::
fromBase64
(
image_data_b64
);
if
(
image_data
.
size
()
<=
1024
)
// must be at least 1kb
continue
;
bool
success
=
false
;
success
=
cover
.
loadFromData
(
image_data
);
if
(
!
success
)
success
=
cover
.
loadFromData
(
image_data_b64
);
if
(
success
)
break
;
}
}
return
cover
;
}
bool
VorbisCommentTagHelper
::
setEmbeddedCover
(
const
QImage
&
cover
)
{
// NOTE since the COVERART tag is not standardized and a proper way has been defined recently [1],
// we should wait until taglib provides an implementation.
// [1] http://wiki.xiph.org/index.php/VorbisComment#Cover_art
#ifdef TAGLIB_HAS_FLAC_PICTURELIST
if
(
m_flacFile
)
{
QByteArray
bytes
;
QBuffer
buffer
(
&
bytes
);
buffer
.
open
(
QIODevice
::
WriteOnly
);
if
(
!
cover
.
save
(
&
buffer
,
"JPEG"
)
)
{
buffer
.
close
();
return
false
;
}
buffer
.
close
();
// back up covers
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>
backedUpPictures
;
const
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>
picturelist
=
m_flacFile
->
pictureList
();
for
(
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>::
ConstIterator
it
=
picturelist
.
begin
();
it
!=
picturelist
.
end
();
it
++
)
{
const
TagLib
::
FLAC
::
Picture
*
picture
=
*
it
;
TagLib
::
FLAC
::
Picture
*
backedUpPicture
=
new
TagLib
::
FLAC
::
Picture
();
backedUpPicture
->
setData
(
picture
->
data
()
);
backedUpPicture
->
setMimeType
(
picture
->
mimeType
()
);
backedUpPicture
->
setType
(
picture
->
type
()
);
backedUpPicture
->
setDescription
(
picture
->
description
()
);
backedUpPictures
.
append
(
backedUpPicture
);
}
// remove all covers
m_flacFile
->
removePictures
();
// add new cover
TagLib
::
FLAC
::
Picture
*
newPicture
=
new
TagLib
::
FLAC
::
Picture
();
newPicture
->
setData
(
TagLib
::
ByteVector
(
bytes
.
data
(),
bytes
.
size
()
)
);
newPicture
->
setMimeType
(
"image/jpeg"
);
newPicture
->
setType
(
TagLib
::
FLAC
::
Picture
::
FrontCover
);
m_flacFile
->
addPicture
(
newPicture
);
// re-add all the backed-up covers except the front cover
for
(
TagLib
::
List
<
TagLib
::
FLAC
::
Picture
*>::
Iterator
it
=
backedUpPictures
.
begin
();
it
!=
backedUpPictures
.
end
();
it
++
)
{
TagLib
::
FLAC
::
Picture
*
picture
=
*
it
;
if
(
picture
->
type
()
!=
TagLib
::
FLAC
::
Picture
::
FrontCover
)
{
m_flacFile
->
addPicture
(
picture
);
}
}
return
true
;
}
#endif // TAGLIB_HAS_FLAC_PICTURELIST
return
false
;
}
#endif //UTILITIES_BUILD
shared/tag_helpers/VorbisCommentTagHelper.h
View file @
717342ed
...
...
@@ -21,6 +21,7 @@
#include
"TagHelper.h"
#include
<taglib/xiphcomment.h>
#include
<taglib/flacfile.h>
namespace
Meta
{
...
...
@@ -30,14 +31,22 @@ namespace Meta
{
public:
VorbisCommentTagHelper
(
TagLib
::
Tag
*
tag
,
TagLib
::
Ogg
::
XiphComment
*
commentsTag
,
Amarok
::
FileType
fileType
);
VorbisCommentTagHelper
(
TagLib
::
Tag
*
tag
,
TagLib
::
Ogg
::
XiphComment
*
commentsTag
,
TagLib
::
FLAC
::
File
*
file
,
Amarok
::
FileType
fileType
);
virtual
Meta
::
FieldHash
tags
()
const
;
virtual
bool
setTags
(
const
Meta
::
FieldHash
&
changes
);
virtual
TagLib
::
ByteVector
render
()
const
;
#ifndef UTILITIES_BUILD
virtual
bool
hasEmbeddedCover
()
const
;
virtual
QImage
embeddedCover
()
const
;
virtual
bool
setEmbeddedCover
(
const
QImage
&
cover
);
#endif //UTILITIES_BUILD
private:
TagLib
::
Ogg
::
XiphComment
*
m_tag
;
TagLib
::
FLAC
::
File
*
m_flacFile
;
};
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment