1 package com.webstersmalley.iplayer.organiser;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 import java.io.File;
21 import java.io.FilenameFilter;
22
23 import org.apache.log4j.Logger;
24 import org.blinkenlights.jid3.ID3Exception;
25 import org.blinkenlights.jid3.ID3Tag;
26 import org.blinkenlights.jid3.MP3File;
27 import org.blinkenlights.jid3.MediaFile;
28 import org.blinkenlights.jid3.v1.ID3V1_0Tag;
29 import org.blinkenlights.jid3.v1.ID3V1_1Tag;
30 import org.blinkenlights.jid3.v1.ID3V1Tag.Genre;
31 import org.blinkenlights.jid3.v2.ID3V2Tag;
32 import org.blinkenlights.jid3.v2.ID3V2_3_0Tag;
33 import org.springframework.context.ApplicationContext;
34 import org.springframework.context.support.ClassPathXmlApplicationContext;
35
36 import com.webstersmalley.iplayer.mp3.MP3Utils;
37
38 public class Retagger {
39 protected class MP3FilenameFilter implements FilenameFilter {
40
41 public boolean accept(File dir, String name) {
42 return name.toLowerCase().matches(".*\\.mp3");
43 }
44
45 }
46
47 private Logger logger = Logger.getLogger(getClass());
48
49 private String inputFolder;
50 private String outputFolder;
51 private RadioProgramBeanFactory beanFactory;
52
53 public RadioProgramBeanFactory getBeanFactory() {
54 return beanFactory;
55 }
56
57 public void setBeanFactory(RadioProgramBeanFactory beanFactory) {
58 this.beanFactory = beanFactory;
59 }
60
61 public String getInputFolder() {
62 return inputFolder;
63 }
64
65 public void setInputFolder(String inputFolder) {
66 this.inputFolder = inputFolder;
67 }
68
69 public String getOutputFolder() {
70 return outputFolder;
71 }
72
73 public void setOutputFolder(String outputFolder) {
74 this.outputFolder = outputFolder;
75 }
76
77 private void rewriteID3Tags(File mp3file, RadioProgramBean bean) {
78
79 logger.info("Title: " + bean.getEpisodeTitle());
80 logger.info("Info: " + bean);
81 MediaFile mediaFile = new MP3File(mp3file);
82 boolean tagsExist = false;
83 try {
84 ID3Tag[] tags = mediaFile.getTags();
85 mediaFile.removeTags();
86 for (ID3Tag tag : tags) {
87 if (tag instanceof ID3V1_0Tag) {
88 logger.info("Rewriting id3 1.0 tag");
89 ID3V1_0Tag v10tag = (ID3V1_0Tag) tag;
90 v10tag.setTitle(bean.getEpisodeTitle());
91 v10tag.setGenre(Genre.Vocal);
92 v10tag.setAlbum(bean.getSeriesTitle());
93 v10tag.setArtist(bean.getArtist());
94 mediaFile.setID3Tag(v10tag);
95 tagsExist = true;
96 } else if (tag instanceof ID3V1_1Tag) {
97 logger.info("Rewriting id3 1.1 tag");
98 ID3V1_1Tag v11tag = (ID3V1_1Tag) tag;
99 v11tag.setTitle(bean.getEpisodeTitle());
100 v11tag.setGenre(Genre.Vocal);
101 v11tag.setAlbum(bean.getSeriesTitle());
102 v11tag.setArtist(bean.getArtist());
103 mediaFile.setID3Tag(v11tag);
104 tagsExist = true;
105 } else if (tag instanceof ID3V2Tag) {
106 logger.info("Rewriting id3 2 tag");
107 ID3V2Tag v2tag = (ID3V2Tag) tag;
108 v2tag.setTitle(bean.getEpisodeTitle());
109 v2tag.setGenre("Audio book/play");
110 v2tag.setAlbum(bean.getSeriesTitle());
111 v2tag.setArtist(bean.getArtist());
112 mediaFile.setID3Tag(v2tag);
113 tagsExist = true;
114 } else if (tag instanceof ID3V2_3_0Tag) {
115 logger.info("Rewriting id3 2.3.0 tag");
116 ID3V2_3_0Tag v230tag = (ID3V2_3_0Tag) tag;
117 v230tag.setTitle(bean.getEpisodeTitle());
118 v230tag.setGenre("Audio book/play");
119 v230tag.setAlbum(bean.getSeriesTitle());
120 v230tag.setArtist(bean.getArtist());
121 mediaFile.setID3Tag(v230tag);
122 tagsExist = true;
123 }
124 }
125 if (!tagsExist) {
126 logger.info("Creating new tag");
127 ID3V2_3_0Tag tag = new ID3V2_3_0Tag();
128 tag.setTitle(bean.getEpisodeTitle());
129 mediaFile.setID3Tag(tag);
130 }
131 mediaFile.sync();
132 } catch (ID3Exception e) {
133 logger.error("Error updating tags: ", e);
134 throw new RuntimeException("Error updating tags: " + e.getMessage());
135 }
136 }
137
138 private void moveFile(File file, RadioProgramBean bean) {
139 String folder = outputFolder + File.separator + bean.getFolder();
140 String filename = folder + File.separator + bean.getFilename();
141
142 File folderFile = new File(folder);
143 if (!folderFile.exists()) {
144 if (!folderFile.mkdirs()) {
145 throw new RuntimeException("Error creating folder: " + folder);
146 }
147 } else {
148 if (!folderFile.isDirectory()) {
149 throw new RuntimeException("Error creating folder: " + folder + " - it already exists but is not a directory...!");
150 }
151 }
152 file.renameTo(new File(filename));
153 }
154
155 private void processFile(File file) {
156 RadioProgramBean bean = beanFactory.getBeanFromFile(file.getName());
157 rewriteID3Tags(file, bean);
158 moveFile(file, bean);
159 }
160
161 public void go() {
162 logger.info("Opening folder: " + inputFolder);
163 File folder = new File(inputFolder);
164 if (!folder.isDirectory()) {
165 throw new RuntimeException("Given folder name is not a folder or does not exist");
166 }
167 File[] files = folder.listFiles(new MP3FilenameFilter());
168
169 for (File file : files) {
170 processFile(file);
171 }
172 }
173
174 public static void main(String[] args) {
175 ApplicationContext ac = new ClassPathXmlApplicationContext("beans-production.xml");
176 Retagger retagger = (Retagger) ac.getBean("retagger");
177 retagger.go();
178 }
179 }