package mp4.util; import java.io.File; import java.io.StringReader; import java.net.MalformedURLException; import java.net.URI; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.xml.transform.sax.SAXSource; import org.xml.sax.InputSource; import mp4.util.atom.Atom; import mp4.util.atom.DataAtom; import mp4.util.atom.MoovAtom; import mp4.util.atom.UdtaAtom; import mp4.util.atom.moov.udta.MetaAtom; import mp4.util.atom.moov.udta.meta.IlstAtom; import mp4.util.atom.moov.udta.meta.ilst.CovrAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtalbAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtartAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtcmtAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtdayAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtnamAtom; import mp4.util.atom.moov.udta.meta.ilst.CprtwrtAtom; import mp4.util.atom.moov.udta.meta.ilst.DescAtom; import mp4.util.atom.moov.udta.meta.ilst.GnreAtom; import mp4.util.atom.moov.udta.meta.ilst.TvenAtom; import mp4.util.atom.moov.udta.meta.ilst.TvshAtom; public class MP4MetadataModule // extends BaseMetadataModule { // public static ConfigEntry cfgMp4Metadata = new ConfigEntry( // "meta.mp4.disable", // "false", // "Disable mp4 metadata processing" // ); // @Override public boolean initialize( // StreamBabyModule m ) { // super.initialize(m); // if (cfgMp4Metadata.getBool() == true) // return false; return true; } public static final int PRIORITY=40; public int getSimplePriority() { return PRIORITY; } public int getMetadataPriority() { return PRIORITY; } public boolean fetchMetadata(MoovAtom moov, URI uri // , MetaData m ) { UdtaAtom udta = moov.getUdta(); MetaAtom meta = null; if (udta != null) { meta = (MetaAtom)moov.getUdta().getFirstChild(MetaAtom.class); } if (meta == null) return false; IlstAtom ilst = (IlstAtom)meta.getFirstChild(IlstAtom.class); if (ilst == null) return false; Map<String, String> metaMap = new HashMap<String, String>(); Iterator<Atom> it = ilst.getChildAtoms().iterator(); while(it.hasNext()) { Atom box = it.next(); if (box instanceof DescAtom) metaMap.put("name", ((DescAtom)box).getDescription()); else if (box instanceof CprtartAtom) metaMap.put("artist", ((CprtartAtom)box).getArtist()); else if (box instanceof CprtalbAtom) metaMap.put("album", ((CprtalbAtom)box).getAlbum()); else if (box instanceof CprtcmtAtom) metaMap.put("comment", ((CprtcmtAtom)box).getComment()); else if (box instanceof CprtAtom) metaMap.put("copyright", ((CprtAtom)box).getCopyright()); else if (box instanceof GnreAtom) metaMap.put("genre", ((GnreAtom)box).getGenre()); else if (box instanceof CprtdayAtom) { String year = ((CprtdayAtom)box).getYear(); if (year.length() > 4) year = year.substring(0, 4); metaMap.put("year", year); } /* } else if (box instanceof AppleTrackNumberBox) metaMap.put("tracknumber", Integer.toString(((AppleTrackNumberBox)box).getTrackNumber())); */ else if (box instanceof CprtwrtAtom) metaMap.put("trackauthor", ((CprtwrtAtom)box).getComposer()); else if (box instanceof CprtnamAtom) metaMap.put("tracktitle", ((CprtnamAtom)box).getTitle()); /* else if (box instanceof AppleTvEpisodeBox) metaMap.put("tvepisodenumber", Integer.toString(((AppleTvEpisodeBox)box).getTvEpisode())); else if (box instanceof AppleTvSeasonBox) metaMap.put("tvseasonnumber", Integer.toString(((AppleTvSeasonBox)box).getTvSeason())); */ else if (box instanceof TvshAtom) metaMap.put("tvshowname", ((TvshAtom)box).getShowName()); else if (box instanceof TvenAtom) metaMap.put("tvepisodenumber", ((TvenAtom)box).getEpisodeNumber()); else if (box instanceof CovrAtom) { CovrAtom covr = (CovrAtom)box; DataAtom data = covr.getDataAtom(); String ext = null; if (data.getFlag()[2] == 13) ext = ".jpg"; else if (data.getFlag()[2] == 14) ext = ".gif"; if (ext != null) { String filename = null; // writeArtwork(uri, data.getMetadata(), ext); if (filename != null) { try { metaMap.put("artwork", new File(filename).toURL().toExternalForm()); } catch (MalformedURLException e) { } } } } } if (metaMap != null && metaMap.size() >0) { StringBuffer data = new StringBuffer(); data.append("<meta>\n"); for (Map.Entry<String, String> e : metaMap.entrySet()) { data.append("<" + e.getKey() + ">"); data.append("<![CDATA["); data.append(e.getValue()); data.append("]]>"); data.append("</" + e.getKey() + ">"); } data.append("</meta>"); // if (metaMap.get("tracktitle") != null) // m.setTitle(metaMap.get("tracktitle")); // else if (metaMap.get("name") != null) // m.setTitle(metaMap.get("name")); SAXSource source = new SAXSource(new InputSource(new StringReader(data.toString()))); // return transform(m, source, StreamBabyConfig.cfgMetaXsl.getValue(), null); return true; } return false; } // public boolean parseIsoBoxes(URI uri, File f, MetaData m) { // DataInputStream mp4file = null; // try { // mp4file = new DataInputStream(new RandomAccessFileInputStream(f)); // Mp4Parser parser = new Mp4Parser(mp4file); // parser.parseMp4(); // mp4file.close(); // return fetchMetadata(parser.getMoov(), uri, m); // } catch (IOException e) { // return false; // } catch (AtomException e) { // return false; // } finally { // if (mp4file != null) { // try { // mp4file.close(); // } catch(IOException ee) { } // } // } // } /* for (Box box : appleItems) { if (box instanceof AppleNameBox) metaMap.put("name", ((AppleNameBox)box).getName()); else if (box instanceof AppleArtistBox) metaMap.put("artist", ((AppleArtistBox)box).getArtist()); else if (box instanceof AppleAlbumBox) metaMap.put("album", ((AppleAlbumBox)box).getAlbumTitle()); else if (box instanceof AppleCommentBox) metaMap.put("comment", ((AppleCommentBox)box).getComment()); else if (box instanceof AppleCopyrightBox) metaMap.put("copyright", ((AppleCopyrightBox)box).getCopyright()); else if (box instanceof AppleCustomGenreBox) metaMap.put("genre", ((AppleCustomGenreBox)box).getGenre()); else if (box instanceof AppleRecordingYearBox) { String year = ((AppleRecordingYearBox)box).getRecordingYear(); if (year.length() > 4) year = year.substring(0, 4); metaMap.put("year", year); } else if (box instanceof AppleTrackNumberBox) metaMap.put("tracknumber", Integer.toString(((AppleTrackNumberBox)box).getTrackNumber())); else if (box instanceof AppleTrackAuthorBox) metaMap.put("trackauthor", ((AppleTrackAuthorBox)box).getTrackAuthor()); else if (box instanceof AppleTrackTitleBox) metaMap.put("tracktitle", ((AppleTrackTitleBox)box).getTrackTitle()); else if (box instanceof AppleTvEpisodeBox) metaMap.put("tvepisodenumber", Integer.toString(((AppleTvEpisodeBox)box).getTvEpisode())); else if (box instanceof AppleTvSeasonBox) metaMap.put("tvseasonnumber", Integer.toString(((AppleTvSeasonBox)box).getTvSeason())); else if (box instanceof AppleCoverBox) { AppleCoverBox coverBox = (AppleCoverBox)box; Box[] dataBoxes = coverBox.getBoxes(); if (dataBoxes != null && dataBoxes.length > 0) { AppleDataBox dataBox = (AppleDataBox)dataBoxes[0]; String ext = null; if (dataBox.getFlags() == 13) ext = ".jpg"; else if (dataBox.getFlags() == 14) ext = ".gif"; if (ext != null) { String filename = writeArtwork(uri, dataBox.getContent(), ext); if (filename != null) metaMap.put("artwork", new File(filename).toURL().toExternalForm()); if (metaMap != null && metaMap.size() >0) { StringBuffer data = new StringBuffer(); data.append("<meta>\n"); for (Map.Entry<String, String> e : metaMap.entrySet()) { data.append("<" + e.getKey() + ">"); data.append("<![CDATA["); data.append(e.getValue()); data.append("]]>"); data.append("</" + e.getKey() + ">"); } data.append("</meta>"); if (metaMap.get("name") != null) m.setTitle(metaMap.get("name")); else if (metaMap.get("tracktitle") != null) m.setTitle(metaMap.get("tracktitle")); */ // public boolean setMetadata(MetaData m, URI uri, VideoInformation vi) { // if (!Utils.isFile(uri)) // return false; // if (m.isBasicInfoOnly()) // return false; // File f = new File(uri); // String lowerCaseName = f.getName(); // if (lowerCaseName.endsWith(".mp4") || lowerCaseName.endsWith(".mov") || lowerCaseName.endsWith(".m4a") || lowerCaseName.endsWith(".m4v")) { // try { // m.setReference(f); // return parseIsoBoxes(uri, f, m); // } catch (Exception e) { //// Log.error("Error parsing mp4 information"); //// Log.printStackTrace(e); // } // } // return false; // } }