Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-1.1
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-1.1
Commits
e871dbed
Commit
e871dbed
authored
Nov 30, 2008
by
Rémi Duraffort
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Taglib: cleaning and better use of the tag library.
parent
a7317a9a
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
174 additions
and
165 deletions
+174
-165
modules/meta_engine/taglib.cpp
modules/meta_engine/taglib.cpp
+174
-165
No files found.
modules/meta_engine/taglib.cpp
View file @
e871dbed
/*****************************************************************************
* taglib.cpp: Taglib tag parser/writer
*****************************************************************************
* Copyright (C) 2003-200
6
the VideoLAN team
* Copyright (C) 2003-200
8
the VideoLAN team
* $Id$
*
* Authors: Clément Stenac <zorglub@videolan.org>
...
...
@@ -41,19 +41,30 @@
#endif
#include <fileref.h>
#include <tag.h>
#include <tstring.h>
#include <id3v2tag.h>
#include <xiphcomment.h>
#include <apetag.h>
#include <flacfile.h>
#include <mpcfile.h>
#include <mpegfile.h>
#include <oggfile.h>
#include <oggflacfile.h>
#include <speexfile.h>
#include <vorbisfile.h>
#include <trueaudiofile.h>
#include <wavpackfile.h>
#include <tstring.h>
#include <textidentificationframe.h>
#include <tbytevector.h>
#include <mpegfile.h>
#include <attachedpictureframe.h>
//#include <oggflacfile.h> /* ogg flac files aren't auto-casted by TagLib */
#include <flacfile.h>
#include <flacproperties.h>
#include <vorbisfile.h>
#include <vorbisproperties.h>
#include <xiphcomment.h>
#include <uniquefileidentifierframe.h>
#include <textidentificationframe.h>
//#include <relativevolumeframe.h> /* parse the tags without TagLib helpers? */
...
...
@@ -75,6 +86,8 @@ vlc_module_end ()
using
namespace
TagLib
;
/* Try detecting embedded art */
static
void
DetectImage
(
FileRef
f
,
demux_t
*
p_demux
)
{
...
...
@@ -239,182 +252,134 @@ static void DetectImage( FileRef f, demux_t *p_demux )
#endif
}
static
int
ReadMeta
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_meta_t
*
p_demux_meta
=
(
demux_meta_t
*
)
p_demux
->
p_private
;
vlc_meta_t
*
p_meta
;
TagLib
::
FileRef
f
;
TAB_INIT
(
p_demux_meta
->
i_attachments
,
p_demux_meta
->
attachments
);
p_demux_meta
->
p_meta
=
NULL
;
#if defined(WIN32) || defined (UNDER_CE)
if
(
GetVersion
()
<
0x80000000
)
{
wchar_t
wpath
[
MAX_PATH
+
1
];
if
(
!
MultiByteToWideChar
(
CP_UTF8
,
0
,
p_demux
->
psz_path
,
-
1
,
wpath
,
MAX_PATH
)
)
return
VLC_EGENERIC
;
wpath
[
MAX_PATH
]
=
L'0'
;
f
=
FileRef
(
wpath
);
}
else
return
VLC_EGENERIC
;
#else
const
char
*
local_name
=
ToLocale
(
p_demux
->
psz_path
);
if
(
local_name
==
NULL
)
return
VLC_EGENERIC
;
f
=
FileRef
(
local_name
);
LocaleFree
(
local_name
);
#endif
if
(
f
.
isNull
()
)
return
VLC_EGENERIC
;
/**
* Read meta informations from APE tags
* @param tag: the APE tag
* @param p_meta: the meta
* @return VLC_SUCCESS if everything goes ok
*/
static
int
ReadMetaFromAPE
(
APE
::
Tag
*
tag
,
vlc_meta_t
*
p_meta
)
{
return
VLC_SUCCESS
;
}
if
(
!
f
.
tag
()
||
f
.
tag
()
->
isEmpty
()
)
return
VLC_EGENERIC
;
p_demux_meta
->
p_meta
=
p_meta
=
vlc_meta_New
();
Tag
*
p_tag
=
f
.
tag
();
if
(
MPEG
::
File
*
p_mpeg
=
dynamic_cast
<
MPEG
::
File
*>
(
f
.
file
()
)
)
{
if
(
p_mpeg
->
ID3v2Tag
()
)
{
ID3v2
::
Tag
*
p_tag
=
p_mpeg
->
ID3v2Tag
();
ID3v2
::
FrameList
list
=
p_tag
->
frameListMap
()[
"UFID"
];
ID3v2
::
UniqueFileIdentifierFrame
*
p_ufid
;
for
(
ID3v2
::
FrameList
::
Iterator
iter
=
list
.
begin
();
iter
!=
list
.
end
();
iter
++
)
/**
* read meta information from id3v2 tags
* @param tag: the id3v2 tag
* @param p_meta: the meta
* @return VLC_SUCCESS if everything goes ok
*/
static
int
ReadMetaFromId2v2
(
ID3v2
::
Tag
*
tag
,
vlc_meta_t
*
p_meta
)
{
// Get the unique file identifier
ID3v2
::
FrameList
list
=
tag
->
frameListMap
()[
"UFID"
];
ID3v2
::
FrameList
::
Iterator
iter
;
for
(
iter
=
list
.
begin
();
iter
!=
list
.
end
();
iter
++
)
{
p_ufid
=
dynamic_cast
<
ID3v2
::
UniqueFileIdentifierFrame
*>
(
*
iter
);
ID3v2
::
UniqueFileIdentifierFrame
*
p_ufid
=
dynamic_cast
<
ID3v2
::
UniqueFileIdentifierFrame
*>
(
*
iter
);
const
char
*
owner
=
p_ufid
->
owner
().
toCString
();
if
(
!
strcmp
(
owner
,
"http://musicbrainz.org"
))
{
/* ID3v2 UFID contains up to 64 bytes binary data
* but in our case it will be a '\0'
* terminated string */
char
*
psz_ufid
=
(
char
*
)
malloc
(
64
)
;
char
psz_ufid
[
64
]
;
int
j
=
0
;
if
(
psz_ufid
)
{
while
(
(
j
<
63
)
&&
(
j
<
p_ufid
->
identifier
().
size
()
)
)
psz_ufid
[
j
]
=
p_ufid
->
identifier
()[
j
++
];
psz_ufid
[
j
]
=
'\0'
;
vlc_meta_SetTrackID
(
p_meta
,
psz_ufid
);
free
(
psz_ufid
);
}
}
}
list
=
p_tag
->
frameListMap
()[
"TXXX"
];
ID3v2
::
UserTextIdentificationFrame
*
p_txxx
;
for
(
ID3v2
::
FrameList
::
Iterator
iter
=
list
.
begin
();
iter
!=
list
.
end
();
iter
++
)
{
p_txxx
=
dynamic_cast
<
ID3v2
::
UserTextIdentificationFrame
*>
(
*
iter
);
const
char
*
psz_desc
=
p_txxx
->
description
().
toCString
();
vlc_meta_AddExtra
(
p_meta
,
psz_desc
,
p_txxx
->
fieldList
().
toString
().
toCString
());
}
#if 0
list = p_tag->frameListMap()["RVA2"];
ID3v2::RelativeVolumeFrame* p_rva2;
for( ID3v2::FrameList::Iterator iter = list.begin();
iter != list.end(); iter++ )
// Get the use text
list
=
tag
->
frameListMap
()[
"TXXX"
];
for
(
iter
=
list
.
begin
();
iter
!=
list
.
end
();
iter
++
)
{
p_rva2 = dynamic_cast<ID3v2::RelativeVolumeFrame*>(*iter);
/* TODO: process rva2 frames */
ID3v2
::
UserTextIdentificationFrame
*
p_txxx
=
dynamic_cast
<
ID3v2
::
UserTextIdentificationFrame
*>
(
*
iter
);
vlc_meta_AddExtra
(
p_meta
,
p_txxx
->
description
().
toCString
(
true
),
p_txxx
->
fieldList
().
toString
().
toCString
(
true
)
);
}
#endif
list
=
p_tag
->
frameList
();
ID3v2
::
Frame
*
p_t
;
char
psz_tag
[
4
];
for
(
ID3v2
::
FrameList
::
Iterator
iter
=
list
.
begin
();
iter
!=
list
.
end
();
iter
++
)
{
p_t
=
dynamic_cast
<
ID3v2
::
Frame
*>
(
*
iter
);
memcpy
(
psz_tag
,
p_t
->
frameID
().
data
(),
4
);
#define SET( foo, bar ) if( !strncmp( psz_tag, foo, 4 ) ) \
vlc_meta_Set##bar( p_meta, p_t->toString().toCString(true))
SET
(
"TPUB"
,
Publisher
);
// Get some more informations
#define SET( tagName, metaName ) \
list = tag->frameListMap()[tagName]; \
if( !list.isEmpty() ) \
vlc_meta_Set##metaName( p_meta, \
(*list.begin())->toString().toCString( true ) );
SET
(
"TCOP"
,
Copyright
);
SET
(
"TENC"
,
EncodedBy
);
SET
(
"TLAN"
,
Language
);
//SET( "POPM", Rating ); /* rating needs special handling in id3v2 */
//if( !strncmp( psz_tag, "RVA2", 4 ) )
/* TODO */
SET
(
"TPUB"
,
Publisher
);
#undef SET
}
}
}
return
VLC_SUCCESS
;
}
else
if
(
Ogg
::
Vorbis
::
File
*
p_ogg_v
=
dynamic_cast
<
Ogg
::
Vorbis
::
File
*>
(
f
.
file
()
)
)
{
int
i_ogg_v_length
=
p_ogg_v
->
audioProperties
()
->
length
();
input_thread_t
*
p_input
=
(
input_thread_t
*
)
vlc_object_find
(
p_demux
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
if
(
p_input
)
{
input_item_t
*
p_item
=
input_GetItem
(
p_input
);
if
(
p_item
)
input_item_SetDuration
(
p_item
,
(
mtime_t
)
i_ogg_v_length
*
1000000
);
vlc_object_release
(
p_input
);
}
}
#if 0 /* at this moment, taglib is unable to detect ogg/flac files
* becauses type detection is based on file extension:
* ogg = ogg/vorbis
* flac = flac
* ø = ogg/flac
*/
else if( Ogg::FLAC::File *p_ogg_f =
dynamic_cast<Ogg::FLAC::File *>(f.file() ) )
{
long i_ogg_f_length = p_ogg_f->streamLength();
input_thread_t *p_input = (input_thread_t *)
vlc_object_find( p_demux, VLC_OBJECT_INPUT, FIND_PARENT );
if( p_input )
{
input_item_t *p_item = input_GetItem( p_input );
if( p_item )
input_item_SetDuration( p_item,
(mtime_t) i_ogg_f_length * 1000000 );
vlc_object_release( p_input );
}
}
#endif
else
if
(
FLAC
::
File
*
p_flac
=
dynamic_cast
<
FLAC
::
File
*>
(
f
.
file
()
)
)
{
long
i_flac_length
=
p_flac
->
audioProperties
()
->
length
();
input_thread_t
*
p_input
=
(
input_thread_t
*
)
vlc_object_find
(
p_demux
,
VLC_OBJECT_INPUT
,
FIND_PARENT
);
if
(
p_input
)
{
input_item_t
*
p_item
=
input_GetItem
(
p_input
);
if
(
p_item
)
input_item_SetDuration
(
p_item
,
(
mtime_t
)
i_flac_length
*
1000000
);
vlc_object_release
(
p_input
);
}
}
/**
* Read the meta informations from XiphComments
* @param tag: the Xiph Comment
* @param p_meta: the meta
* @return VLC_SUCCESS if everything goes ok
*/
static
int
ReadMetaFromXiph
(
Ogg
::
XiphComment
*
tag
,
vlc_meta_t
*
p_meta
)
{
return
VLC_SUCCESS
;
}
#define SET( foo, bar ) if( !p_tag->bar ().isNull() && !p_tag->bar ().isEmpty() ) \
vlc_meta_Set##foo( p_meta, p_tag->bar ().toCString(true))
#define SETINT( foo, bar ) { \
/**
* Get the tags from the file using TagLib
* @param p_this: the demux object
* @return VLC_SUCCESS if the operation success
*/
static
int
ReadMeta
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
demux_meta_t
*
p_demux_meta
=
(
demux_meta_t
*
)
p_demux
->
p_private
;
vlc_meta_t
*
p_meta
;
TagLib
::
FileRef
f
;
p_demux_meta
->
p_meta
=
NULL
;
const
char
*
local_name
=
ToLocale
(
p_demux
->
psz_path
);
if
(
!
local_name
)
return
VLC_EGENERIC
;
f
=
FileRef
(
local_name
);
LocaleFree
(
local_name
);
if
(
f
.
isNull
()
)
return
VLC_EGENERIC
;
if
(
!
f
.
tag
()
||
f
.
tag
()
->
isEmpty
()
)
return
VLC_EGENERIC
;
p_demux_meta
->
p_meta
=
p_meta
=
vlc_meta_New
();
if
(
!
p_meta
)
return
VLC_ENOMEM
;
// Read the tags from the file
Tag
*
p_tag
=
f
.
tag
();
#define SET( meta, tag ) \
if( !p_tag->tag().isNull() && !p_tag->tag().isEmpty() ) \
vlc_meta_Set##meta( p_meta, p_tag->tag().toCString(true) )
#define SETINT( meta, tag ) \
if( p_tag->tag() ) \
{ \
char psz_tmp[10]; \
snprintf(
(char*)psz_tmp, 10, "%d", p_tag->bar() );
\
vlc_meta_Set##
foo( p_meta, (char*)psz_tmp );
\
snprintf(
psz_tmp, 10, "%d", p_tag->tag() );
\
vlc_meta_Set##
meta( p_meta, psz_tmp );
\
}
SET
(
Title
,
title
);
...
...
@@ -423,15 +388,59 @@ vlc_meta_Set##bar( p_meta, p_t->toString().toCString(true))
SET
(
Description
,
comment
);
SET
(
Genre
,
genre
);
SETINT
(
Date
,
year
);
SETINT
(
Tracknum
,
track
);
#undef SET
SETINT
(
Tracknum
,
track
);
#undef SETINT
#undef SET
// Try now to read special tags
if
(
FLAC
::
File
*
flac
=
dynamic_cast
<
FLAC
::
File
*>
(
f
.
file
())
)
{
if
(
flac
->
ID3v2Tag
()
)
ReadMetaFromId2v2
(
flac
->
ID3v2Tag
(),
p_meta
);
else
if
(
flac
->
xiphComment
()
)
ReadMetaFromXiph
(
flac
->
xiphComment
(),
p_meta
);
}
else
if
(
MPC
::
File
*
mpc
=
dynamic_cast
<
MPC
::
File
*>
(
f
.
file
())
)
{
if
(
mpc
->
APETag
()
)
ReadMetaFromAPE
(
mpc
->
APETag
(),
p_meta
);
}
else
if
(
MPEG
::
File
*
mpeg
=
dynamic_cast
<
MPEG
::
File
*>
(
f
.
file
())
)
{
if
(
mpeg
->
ID3v2Tag
()
)
ReadMetaFromId2v2
(
mpeg
->
ID3v2Tag
(),
p_meta
);
else
if
(
mpeg
->
APETag
()
)
ReadMetaFromAPE
(
mpeg
->
APETag
(),
p_meta
);
}
else
if
(
Ogg
::
File
*
ogg
=
dynamic_cast
<
Ogg
::
File
*>
(
f
.
file
())
)
{
if
(
Ogg
::
FLAC
::
File
*
ogg_flac
=
dynamic_cast
<
Ogg
::
FLAC
::
File
*>
(
f
.
file
()))
ReadMetaFromXiph
(
ogg_flac
->
tag
(),
p_meta
);
else
if
(
Ogg
::
Speex
::
File
*
ogg_speex
=
dynamic_cast
<
Ogg
::
Speex
::
File
*>
(
f
.
file
())
)
ReadMetaFromXiph
(
ogg_speex
->
tag
(),
p_meta
);
else
if
(
Ogg
::
Vorbis
::
File
*
ogg_vorbis
=
dynamic_cast
<
Ogg
::
Vorbis
::
File
*>
(
f
.
file
())
)
ReadMetaFromXiph
(
ogg_vorbis
->
tag
(),
p_meta
);
}
else
if
(
TrueAudio
::
File
*
trueaudio
=
dynamic_cast
<
TrueAudio
::
File
*>
(
f
.
file
())
)
{
if
(
trueaudio
->
ID3v2Tag
()
)
ReadMetaFromId2v2
(
trueaudio
->
ID3v2Tag
(),
p_meta
);
}
else
if
(
WavPack
::
File
*
wavpack
=
dynamic_cast
<
WavPack
::
File
*>
(
f
.
file
())
)
{
if
(
wavpack
->
APETag
()
)
ReadMetaFromAPE
(
wavpack
->
APETag
(),
p_meta
);
}
// Try now to find a image
DetectImage
(
f
,
p_demux
);
return
VLC_SUCCESS
;
}
static
int
WriteMeta
(
vlc_object_t
*
p_this
)
{
playlist_t
*
p_playlist
=
(
playlist_t
*
)
p_this
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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