14 typedef struct _ContentTYPE{
20 static CONTENT_TYPE ContentCatList[CAT_COUNT] = {
21 { "¥Ë¥å¡¼¥¹¡¦ÊóÆ»", "news" },
22 { "¥¹¥Ý¡¼¥Ä", "sports" },
23 { "¾ðÊó", "information" },
24 { "¥É¥é¥Þ", "drama" },
26 { "¥Ð¥é¥¨¥Æ¥£", "variety" },
28 { "¥¢¥Ë¥á¡¦Æû£", "anime" },
29 { "¥É¥¥å¥á¥ó¥¿¥ê¡¼¡¦¶µÍÜ", "documentary" },
31 { "¼ñÌ£¡¦¼ÂÍÑ", "hobby" },
32 { "Ê¡»ã", "etc" }, //Ê¡»ã
33 { "ͽÈ÷", "etc" }, //ͽÈ÷
34 { "ͽÈ÷", "etc" }, //ͽÈ÷
35 { "ͽÈ÷", "etc" }, //ͽÈ÷
36 { "¤½¤Î¾", "etc" } //¤½¤Î¾
38 typedef struct _TAG_STATION
42 int tsId; // OriginalNetworkID
43 int onId; // TransportStreamID
44 int svId; // ServiceID
47 static STATION bsSta[] = {
48 { "NHK BS1", "3001.ontvjapan.com", 16625, 4, 101},
49 { "NHK BS2", "3002.ontvjapan.com", 16625, 4, 102},
50 { "NHK BSh", "3003.ontvjapan.com", 16626, 4, 103},
51 { "BSÆü¥Æ¥ì", "3004.ontvjapan.com", 16592, 4, 141},
52 { "BSÄ«Æü", "3005.ontvjapan.com", 16400, 4, 151},
53 { "BS-i", "3006.ontvjapan.com", 16401, 4, 161},
54 { "BS¥¸¥ã¥Ñ¥ó", "3007.ontvjapan.com", 16433, 4, 171},
55 { "BS¥Õ¥¸", "3008.ontvjapan.com", 16593, 4, 181},
56 { "WOWOW", "3009.ontvjapan.com", 16432, 4, 191},
57 { "WOWOW2", "3010.ontvjapan.com", 16432, 4, 192},
58 { "WOWOW3", "3011.ontvjapan.com", 16432, 4, 193},
59 { "BS11", "3013.ontvjapan.com", 16528, 4, 211},
60 { "TwellV", "3014.ontvjapan.com", 16530, 4, 222},
63 static int bsStaCount = sizeof(bsSta) / sizeof (STATION);
67 static STATION csSta[] = {
68 { "¥¹¥¿¡¼£ã£è¥×¥é¥¹", "1002.ontvjapan.com", 24608, 6, 237},
69 { "ÆüËܱDzèÀìÌç£ã£è£È£Ä", "1086.ontvjapan.com", 24608, 6, 239},
70 { "¥Õ¥¸¥Æ¥ì¥Ó£Ã£Ó£È£Ä", "306ch.epgdata.ontvjapan", 24608, 6, 306},
71 { "¥·¥ç¥Ã¥×¥Á¥ã¥ó¥Í¥ë", "1059.ontvjapan.com", 24704, 6, 55},
72 { "¥¶¡¦¥·¥Í¥Þ", "1217.ontvjapan.com", 24736, 6, 228},
73 { "¥¹¥«¥Á¥ã¥ó£È£Ä£¸£°£°", "800ch.epgdata.ontvjapan", 24736, 6, 800},
74 { "¥¹¥«¥Á¥ã¥ó£¸£°£±", "801ch.epgdata.ontvjapan", 24736, 6, 801},
75 { "¥¹¥«¥Á¥ã¥ó£¸£°£²", "802ch.epgdata.ontvjapan", 24736, 6, 802},
76 { "£å£²¥×¥í¥â", "100ch.epgdata.ontvjapan", 28736, 7, 100},
77 { "¥¤¥ó¥¿¡¼¥í¡¼¥«¥ë£Ô£Ö", "194ch.epgdata.ontvjapan", 28736, 7, 194},
78 { "£Ê¥¹¥Ý¡¼¥Ä¡¡£Å£Ó£Ð£Î", "1025.ontvjapan.com", 28736, 7, 256},
79 { "£Æ£Ï£Ø", "1016.ontvjapan.com", 28736, 7, 312},
80 { "¥¹¥Ú¡¼¥¹¥·¥ã¥ï¡¼£Ô£Ö", "1018.ontvjapan.com", 28736, 7, 322},
81 { "¥«¡¼¥È¥¥¡¼¥ó¡¡¥Í¥Ã¥È", "1046.ontvjapan.com", 28736, 7, 331},
82 { "¥È¥¥¡¼¥ó¡¦¥Ç¥£¥º¥Ë¡¼", "1213.ontvjapan.com", 28736, 7, 334},
83 { "Åì±Ç¥Á¥ã¥ó¥Í¥ë", "1010.ontvjapan.com", 28768, 7, 221},
84 { "±ÒÀ±·à¾ì", "1005.ontvjapan.com", 28768, 7, 222},
85 { "¥Á¥ã¥ó¥Í¥ë£Î£Å£Ã£Ï", "1008.ontvjapan.com", 28768, 7, 223},
86 { "Íβè¡ú¥·¥Í¥Õ¥£¥ë", "1009.ontvjapan.com", 28768, 7, 224},
87 { "¥¹¥¿¡¼¡¦¥¯¥é¥·¥Ã¥¯", "1003.ontvjapan.com", 28768, 7, 238},
88 { "»þÂå·àÀìÌç¥Á¥ã¥ó¥Í¥ë", "1133.ontvjapan.com", 28768, 7, 292},
89 { "¥¹¡¼¥Ñ¡¼¥É¥é¥Þ", "1006.ontvjapan.com", 28768, 7, 310},
90 { "£Á£Ø£Î", "1014.ontvjapan.com", 28768, 7, 311},
91 { "¥Ê¥·¥ç¥¸¥ª¥Á¥ã¥ó¥Í¥ë", "1204.ontvjapan.com", 28768, 7, 343},
92 { "¥ï¥ó¥Æ¥ó¥Ý¡¼¥¿¥ë", "110ch.epgdata.ontvjapan", 28864, 7, 110},
93 { "¥´¥ë¥Õ¥Á¥ã¥ó¥Í¥ë", "1028.ontvjapan.com", 28864, 7, 260},
94 { "¥Æ¥ìÄ«¥Á¥ã¥ó¥Í¥ë", "1092.ontvjapan.com", 28864, 7, 303},
95 { "£Í£Ô£Ö", "1019.ontvjapan.com", 28864, 7, 323},
96 { "¥ß¥å¡¼¥¸¥Ã¥¯¡¦¥¨¥¢", "1024.ontvjapan.com", 28864, 7, 324},
97 { "Ä«Æü¥Ë¥å¡¼¥¹¥¿¡¼", "1067.ontvjapan.com", 28864, 7, 352},
98 { "£Â£Â£Ã¥ï¡¼¥ë¥É", "1070.ontvjapan.com", 28864, 7, 353},
99 { "£Ã£Î£Î£ê", "1069.ontvjapan.com", 28864, 7, 354},
100 { "¥¸¥ã¥¹¥È¡¦¥¢¥¤", "361ch.epgdata.ontvjapan", 28864, 7, 361},
101 { "£Ê¥¹¥Ý¡¼¥Ä¡¡£±", "1041.ontvjapan.com", 28896, 7, 251},
102 { "£Ê¥¹¥Ý¡¼¥Ä¡¡£²", "1042.ontvjapan.com", 28896, 7, 252},
103 { "£Ê¥¹¥Ý¡¼¥Ä£Ð£ì£õ£ó£È", "1043.ontvjapan.com", 28896, 7, 253},
104 { "£Ç£Á£Ï£Ò£Á", "1026.ontvjapan.com", 28896, 7, 254},
105 { "£ó£ë£ù¡¦£Á¥¹¥Ý¡¼¥Ä¡Ü", "1040.ontvjapan.com", 28896, 7, 255},
106 { "ÊõÄÍ¥×¥í¥â¥Á¥ã¥ó¥Í¥ë", "101ch.epgdata.ontvjapan", 28928, 7, 101},
107 { "£Ó£Ë£Ù¡¦£Ó£Ô£Á£Ç£Å", "1207.ontvjapan.com", 28928, 7, 290},
108 { "¥Á¥ã¥ó¥Í¥ë¶ä²Ï", "305ch.epgdata.ontvjapan", 28928, 7, 305},
109 { "£Á£Ô-£Ø", "1201.ontvjapan.com", 28928, 7, 333},
110 { "¥Ò¥¹¥È¥ê¡¼¥Á¥ã¥ó¥Í¥ë", "1050.ontvjapan.com", 28928, 7, 342},
111 { "¥¹¥«¥Á¥ã¥ó£¸£°£³", "803ch.epgdata.ontvjapan", 28928, 7, 803},
112 { "¥¹¥«¥Á¥ã¥ó£¸£°£´", "804ch.epgdata.ontvjapan", 28928, 7, 804},
113 { "¥à¡¼¥Ó¡¼¥×¥é¥¹£È£Ä", "1007.ontvjapan.com", 28960, 7, 240},
114 { "¥´¥ë¥Õ¥Í¥Ã¥È¥ï¡¼¥¯", "1027.ontvjapan.com", 28960, 7, 262},
115 { "£Ì£á£Ì£á¡¡£È£Ä", "1074.ontvjapan.com", 28960, 7, 314},
116 { "¥Õ¥¸¥Æ¥ì¥Ó£Ï£Î£Å", "1073.ontvjapan.com", 28992, 7, 307},
117 { "¥Õ¥¸¥Æ¥ì¥Ó£Ô£×£Ï", "1072.ontvjapan.com", 28992, 7, 308},
118 { "¥¢¥Ë¥Þ¥Ã¥¯¥¹", "1047.ontvjapan.com", 28992, 7, 332},
119 { "¥Ç¥£¥¹¥«¥Ð¥ê¡¼", "1062.ontvjapan.com", 28992, 7, 340},
120 { "¥¢¥Ë¥Þ¥ë¥×¥é¥Í¥Ã¥È", "1193.ontvjapan.com", 28992, 7, 341},
121 { "£Ã-£Ô£Â£Ó¥¦¥¨¥ë¥«¥à", "160ch.epgdata.ontvjapan", 29024, 7, 160},
122 { "£Ñ£Ö£Ã", "1120.ontvjapan.com", 29024, 7, 161},
123 { "¥×¥é¥¤¥à£³£¶£µ¡¥£Ô£Ö", "185ch.epgdata.ontvjapan", 29024, 7, 185},
124 { "¥Õ¥¡¥ß¥ê¡¼·à¾ì", "1015.ontvjapan.com", 29024, 7, 293},
125 { "£Ô£Â£Ó¥Á¥ã¥ó¥Í¥ë", "3201.ontvjapan.com", 29024, 7, 301},
126 { "¥Ç¥£¥º¥Ë¡¼¥Á¥ã¥ó¥Í¥ë", "1090.ontvjapan.com", 29024, 7, 304},
127 { "MUSIC ON! TV", "1022.ontvjapan.com", 29024, 7, 325},
128 { "¥¥Ã¥º¥¹¥Æ¡¼¥·¥ç¥ó", "1045.ontvjapan.com", 29024, 7, 330},
129 { "£Ô£Â£Ó¥Ë¥å¡¼¥¹¥Ð¡¼¥É", "1076.ontvjapan.com", 29024, 7, 351},
130 { "£Ã£ÓÆüËÜÈÖÁÈ¥¬¥¤¥É", "147ch.epgdata.ontvjapan", 29056, 7, 147},
131 { "Æü¥Æ¥ì£Ç¡Ü", "1068.ontvjapan.com", 29056, 7, 257},
132 { "fashion TV", "5004.ontvjapan.com", 29056, 7, 291},
133 { "Æü¥Æ¥ì¥×¥é¥¹", "300ch.epgdata.ontvjapan", 29056, 7, 300},
134 { "¥¨¥³¥ß¥å¡¼¥¸¥Ã¥¯£Ô£Ö", "1023.ontvjapan.com", 29056, 7, 320},
135 { "Music Japan TV", "1208.ontvjapan.com", 29056, 7, 321},
136 { "Æü¥Æ¥ì£Î£Å£×£Ó£²£´", "2002.ontvjapan.com", 29056, 7, 350},
139 static int csStaCount = sizeof(csSta) / sizeof (STATION);
140 SVT_CONTROL *svttop = NULL;
144 char desc[102400] = {0};
146 char ServiceName[1024];
149 void xmlspecialchars(char *str)
151 strrep(str, "&", "&");
152 strrep(str, "'", "'");
153 strrep(str, "\"", """);
154 strrep(str, "<", "<");
155 strrep(str, ">", ">");
160 void GetSDT(FILE *infile, SVT_CONTROL *svttop, SECcache *secs, int count)
164 while((bsecs = readTS(infile, secs, count)) != NULL) {
166 if((bsecs->pid & 0xFF) == 0x11) {
167 dumpSDT(bsecs->buf, svttop);
171 void GetEIT(FILE *infile, FILE *outfile, STATION *psta, SECcache *secs, int count)
174 EIT_CONTROL *eitcur ;
175 EIT_CONTROL *eitnext ;
176 EIT_CONTROL *eittop = NULL;
188 eittop = calloc(1, sizeof(EIT_CONTROL));
190 fseek(infile, 0, SEEK_SET);
191 while((bsecs = readTS(infile, secs, SECCOUNT)) != NULL) {
193 if((bsecs->pid & 0xFF) == 0x12) {
194 dumpEIT(bsecs->buf, psta->svId, psta->onId, psta->tsId, eittop);
195 }else if((bsecs->pid & 0xFF) == 0x26) {
196 dumpEIT(bsecs->buf, psta->svId, psta->onId, psta->tsId, eittop);
197 }else if((bsecs->pid & 0xFF) == 0x27) {
198 dumpEIT(bsecs->buf, psta->svId, psta->onId, psta->tsId, eittop);
202 while(eitcur != NULL){
204 eitcur = eitcur->next ;
207 if(eitcur->content_type > CAT_COUNT){
208 eitcur->content_type = CAT_COUNT -1 ;
211 memset(title, '\0', sizeof(title));
212 ilen = strlen(eitcur->title);
213 olen = sizeof(title);
214 inptr = eitcur->title;
215 iconv(cd, &inptr, &ilen, &outptr, &olen);
216 xmlspecialchars(title);
218 memset(subtitle, '\0', sizeof(subtitle));
219 ilen = strlen(eitcur->subtitle);
220 olen = sizeof(subtitle);
222 inptr = eitcur->subtitle;
223 iconv(cd, &inptr, &ilen, &outptr, &olen);
224 xmlspecialchars(subtitle);
226 memset(desc, '\0', sizeof(desc));
227 if ( eitcur->desc ) {
228 ilen = strlen(eitcur->desc);
231 inptr = eitcur->desc;
232 iconv(cd, &inptr, &ilen, &outptr, &olen);
233 xmlspecialchars(desc);
236 memset(Category, '\0', sizeof(Category));
237 ilen = strlen(ContentCatList[eitcur->content_type].japanese);
238 olen = sizeof(Category);
240 inptr = ContentCatList[eitcur->content_type].japanese;
241 iconv(cd, &inptr, &ilen, &outptr, &olen);
242 xmlspecialchars(Category);
244 tl.tm_sec = eitcur->ss ;
245 tl.tm_min = eitcur->hm ;
246 tl.tm_hour = eitcur->hh ;
247 tl.tm_mday = eitcur->dd ;
248 tl.tm_mon = (eitcur->mm - 1);
249 tl.tm_year = (eitcur->yy - 1900);
253 l_time = mktime(&tl);
254 if((eitcur->ehh == 0) && (eitcur->emm == 0) && (eitcur->ess == 0)){
256 end_time = l_time + (60 * 5); // £µÊ¬¸å¤ËÀßÄê
257 endtl = localtime(&end_time);
259 end_time = l_time + eitcur->ehh * 3600 + eitcur->emm * 60 + eitcur->ess;
260 endtl = localtime(&end_time);
262 memset(cendtime, '\0', sizeof(cendtime));
263 memset(cstarttime, '\0', sizeof(cstarttime));
264 strftime(cendtime, (sizeof(cendtime) - 1), "%Y%m%d%H%M%S", endtl);
265 strftime(cstarttime, (sizeof(cstarttime) - 1), "%Y%m%d%H%M%S", &tl);
267 fprintf(outfile, " <programme start=\"%s +0900\" stop=\"%s +0900\" channel=\"%s\">\n",
268 cstarttime, cendtime, psta->ontv);
269 fprintf(outfile, " <title lang=\"ja_JP\">%s</title>\n", title);
270 fprintf(outfile, " <desc lang=\"ja_JP\">%s</desc>\n", subtitle);
271 fprintf(outfile, " <longdesc lang=\"ja_JP\">%s</longdesc>\n", desc);
272 fprintf(outfile, " <category lang=\"ja_JP\">%s</category>\n", Category);
273 fprintf(outfile, " <category lang=\"en\">%s</category>\n", ContentCatList[eitcur->content_type].english);
274 fprintf(outfile, " </programme>\n");
276 fprintf(outfile, "(%x:%x:%x)%s,%s,%s,%s,%s,%s\n",
277 eitcur->servid, eitcur->table_id, eitcur->event_id,
278 cstarttime, cendtime,
281 ContentCatList[eitcur->content_type].english);
284 fprintf(outfile, "(%x:%x)%04d/%02d/%02d,%02d:%02d:%02d,%02d:%02d:%02d,%s,%s,%s,%s\n",
285 eitcur->table_id, eitcur->event_id,
286 eitcur->yy, eitcur->mm, eitcur->dd,
287 eitcur->hh, eitcur->hm, eitcur->ss,
288 eitcur->ehh, eitcur->emm, eitcur->ess,
289 eitcur->title, eitcur->subtitle,
290 ContentCatList[eitcur->content_type].japanese,
291 ContentCatList[eitcur->content_type].english);
293 eitnext = eitcur->next ;
295 free(eitcur->subtitle);
302 int main(int argc, char *argv[])
305 FILE *infile = stdin;
306 FILE *outfile = stdout;
307 int arg_maxcount = 1 ;
316 SVT_CONTROL *svtcur ;
317 SVT_CONTROL *svtsave ;
322 SECcache secs[SECCOUNT];
328 /* ¶½Ì£¤Î¤¢¤ëpid¤ò»ØÄê */
329 memset(secs, 0, sizeof(SECcache) * SECCOUNT);
338 if(strcmp(file, "-")) {
339 infile = fopen(file, "r");
342 if(strcmp(argv[3], "-")) {
343 outfile = fopen(argv[3], "w+");
347 fprintf(stdout, "Usage : %s /BS <tsFile> <outfile>\n", argv[0]);
348 fprintf(stdout, "Usage : %s <ontvcode> <tsFile> <outfile>\n", argv[0]);
349 fprintf(stdout, "ontvcode ¥Á¥ã¥ó¥Í¥ë¼±Ê̻ҡ£****.ontvjapan.com ¤Ê¤É\n");
350 fprintf(stdout, "/BS BS¥â¡¼¥É¡£°ì¤Ä¤ÎTS¤«¤éBSÁ´¶É¤Î¥Ç¡¼¥¿¤òÆɤ߹þ¤ß¤Þ¤¹¡£\n");
351 fprintf(stdout, "/CS CS¥â¡¼¥É¡£°ì¤Ä¤ÎTS¤«¤éÊ£¿ô¶É¤Î¥Ç¡¼¥¿¤òÆɤ߹þ¤ß¤Þ¤¹¡£\n");
355 if(strcmp(arg_onTV, "/BS") == 0){
357 staCount = bsStaCount;
359 }else if(strcmp(arg_onTV, "/CS") == 0){
361 staCount = csStaCount;
365 svttop = calloc(1, sizeof(SVT_CONTROL));
366 GetSDT(infile, svttop, secs, SECCOUNT);
367 svtcur = svttop->next ; //ÀèƬ
373 pStas = calloc(1, sizeof(STATION));
374 pStas->tsId = svtcur->transport_stream_id ;
375 pStas->onId = svtcur->original_network_id ;
376 pStas->svId = svtcur->event_id ;
377 pStas->ontv = arg_onTV ;
378 pStas->name = svtcur->servicename ;
382 fprintf(outfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
383 fprintf(outfile, "<!DOCTYPE tv SYSTEM \"xmltv.dtd\">\n\n");
384 fprintf(outfile, "<tv generator-info-name=\"tsEPG2xml\" generator-info-url=\"http://localhost/\">\n");
386 cd = iconv_open("UTF-8", "EUC-JP");
387 for(lp = 0 ; lp < staCount ; lp++){
388 memset(ServiceName, '\0', sizeof(ServiceName));
389 ilen = strlen(pStas[lp].name);
390 olen = sizeof(ServiceName);
391 outptr = ServiceName ;
392 inptr = pStas[lp].name ;
393 iconv(cd, &inptr, &ilen, &outptr, &olen);
394 xmlspecialchars(ServiceName);
396 fprintf(outfile, " <channel id=\"%s\">\n", pStas[lp].ontv);
397 fprintf(outfile, " <display-name lang=\"ja_JP\">%s</display-name>\n", ServiceName);
398 fprintf(outfile, " </channel>\n");
400 for(lp = 0 ; lp < staCount ; lp++){
401 GetEIT(infile, outfile, &pStas[lp], secs, SECCOUNT);
403 fprintf(outfile, "</tv>\n");
414 svtcur = svttop ; //ÀèƬ
415 while(svtcur != NULL){
416 svtsave = svtcur->next ;