#include "tclist.h"
-static void usage(void){
+static void usage(char *cmd){
+ fprintf(stderr,"Check CM from wavefile(output cmd stdout)\n");
+ fprintf(stderr,"%s: filename.wav\n\n",cmd);
+ fprintf(stderr,"Check CM from mp4file(require ffmpeg or faad cmd)\n");
+ fprintf(stderr,"%s: filename.mp4\n\n",cmd);
+ fprintf(stderr,"Check CM from mp4file and execute cutcmd(create new filename.mp4-new.mp4) \n");
+ fprintf(stderr,"%s: -x filename.mp4\n\n",cmd);
+ fprintf(stderr,"Check CM and manual edit\n");
+ fprintf(stderr,"%s: -b filename.mp4 filename.mp4 > filename-sh\n",cmd);
+ fprintf(stderr,"Edit filename-sh for mis detection and re execute next cmd\n",cmd);
+ fprintf(stderr,"%s: -x filename-sh\n",cmd);
exit(1);
}
char cmflg;
char honpen;
int peak;
+ int stsecfix;
+ int edsecfix;
+ char *fixparam;
}muonst;
static muonst m[1000];
static int thumb=0;
static int txtrecheck=0;
static int cmdexecute=0;
+static int checkcomplete=0;
+static int basets=0;
-static char *MP4BOXCMD="/usr/local/bin/MP4Box -quiet -noprog";
static char *MP4BOXCMDRAPSTR="Adjusting chunk start time to previous random access at ";
+#ifdef __FreeBSD__
+static char *MP4BOXCMD="/usr/local/bin/MP4Box";
static char *SOXCMD="/usr/local/bin/sox";
static char *FFMPEGCMD="/usr/local/bin/ffmpeg";
static char *MPLAYERCMD="/usr/local/bin/mplayer";
static char *AACENCCMD="/usr/local/bin/aacplusenc";
+static char *AACENCOPT="%s '%s.wav' '%s' 60";
+static char *FAADCMD="/usr/local/bin/faad";
+static char *FIXASS="/usr/home/piro/bin/fixass";
+#else
+static char *MP4BOXCMD="MP4Box";
+static char *SOXCMD="sox";
+static char *FFMPEGCMD="ffmpeg";
+static char *MPLAYERCMD="mplayer";
+static char *AACENCCMD="neroAacEnc";
+static char *AACENCOPT="%s -br 60 -if '%s.wav' -of '%s'";
+static char *FAADCMD=NULL;
+static char *FIXASS="fixass";
+#endif
FILE *checkMP4(FILE *f,char *filename)
{
char readbuf[20];
char *cmdbuf;
FILE *pp;
+ char *tmpts;
memset(readbuf,0,sizeof(readbuf));
fread(readbuf,sizeof(readbuf),1,f);
return NULL;
}
// mp4ファイルだったら、ffmpegでwaveに変換し読み込む。
- //sprintf(cmdbuf,"%s -v 0 -i %s -f wav pipe: 2>/dev/null",FFMPEGCMD,filename);
- asprintf(&cmdbuf,"%s -v 0 -i %s -f wav pipe: 2>/dev/null",FFMPEGCMD,filename);
+ if (FAADCMD) {
+ // filename.tmp.ts is exist ?
+ asprintf(&tmpts,"%s.tmp.ts",filename);
+ if (basets && (pp=fopen(tmpts,"r") )) {
+ fclose(pp);
+ pp=NULL;
+ asprintf(&cmdbuf,"%s -d -w -F 0x3330D -q '%s'",FAADCMD,tmpts);
+ }
+ else {
+ asprintf(&cmdbuf,"%s -d -w -q '%s'",FAADCMD,filename);
+}
+
+ free(tmpts);
+ }
+ else
+ asprintf(&cmdbuf,"%s -v 0 -i '%s' -f wav pipe: 2>/dev/null",FFMPEGCMD,filename);
+
pp = popen(cmdbuf,"r");
if (pp == NULL) return NULL;
fclose(f);
if (wkfilename==NULL) return stsec;
- sprintf(cmdbuf,"%s -splitx %.2f:%.2f %s -out /dev/null",MP4BOXCMD,edsec/1000.0,(edsec+10000)/1000.0,wkfilename);
+ sprintf(cmdbuf,"%s -quiet -noprog -splitx %.2f:%.2f '%s' -out /dev/null",MP4BOXCMD,edsec/1000.0,(edsec+10000)/1000.0,wkfilename);
rap=0.0;
pp = popen(cmdbuf,"r");
else return stsec;
}
+int cmpinfo(int mcnt)
+{
+ int i;
+ char *cmdptr,readbuf[20];
+ TCLIST *cmdlist;
+
+ if (!wkfilename) return 0;
+
+ cmdlist = tclistnew();
+
+ asprintf(&cmdptr,"#!/bin/sh");
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+
+
+ for(i=0;i<mcnt;i++) {
+ if (thumb) {
+ asprintf(&cmdptr,"rm -f '%s-%d.png'",wkfilename,i);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+ }
+ }
+ // check new mp4
+ asprintf(&cmdptr,"%s-new.mp4",wkfilename);
+ FILE *fp;
+ fp = fopen(cmdptr,"rb");
+ if (fp==NULL) {
+ //ファイルなし
+ return 0;
+ }
+ fread(readbuf,sizeof(readbuf),1,fp);
+ if (!strstr(readbuf+4,"ftypisom")) {
+ //mp4じゃない感じ(置き換えないときは無視)
+ if (checkcomplete == 1) return 0;
+ }
+ fclose(fp);
+ free(cmdptr);
+
+ if (checkcomplete==1) { //元ファイル置き換え
+ asprintf(&cmdptr,"mv '%s-new.mp4' '%s'",wkfilename,wkfilename);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+ asprintf(&cmdptr,"mv '%s.fix.ass' '%s.ass'",wkfilename,wkfilename);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+ }
+ if (checkcomplete==2) { //CMカットファイル削除
+ asprintf(&cmdptr,"rm -f '%s-new.mp4'",wkfilename);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+ }
+
+ asprintf(&cmdptr,"rm -f '%s-sh'",wkfilename);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+
+ asprintf(&cmdptr,"rm -f '%s.split.log'",wkfilename);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+
+ asprintf(&cmdptr,"rm -f '%s.fix.ass'",wkfilename);
+ tclistpush2(cmdlist,cmdptr);
+ free(cmdptr);
+
+ for(i=0;i<tclistnum(cmdlist);i++) {
+ if (cmdexecute) {
+ FILE *pp;
+ char pbuf[1024];
+ pp = popen(tclistval2(cmdlist,i),"r");
+ if (pp==NULL) {continue;}
+ while(fgets(pbuf,1024,pp)!=NULL){
+ }
+ pclose(pp);
+ }
+ else
+ printf("%s\n",tclistval2(cmdlist,i));
+ }
+
+}
int dumpinfo(int mcnt)
{
int honstart,hcnt,totalsec;
char *cptr,*cptr2,*tfptr;
TCLIST *cmdlist;
TCLIST *tflist;
+ FILE *fp;
honstart=0;
hcnt=0;
printf("#!/bin/sh\n# cmcheckwave %s\n#\n",wkfilename?wkfilename:"");
//カットするため、一連のCM,本編時間を結合
for(i=0;i<mcnt;i++) {
- printf("# %.2f %.2f diff %.2f %s\n",m[i].stsec/1000.0,m[i].edsec/1000.0,m[i].diffs/1000.0,m[i].cmflg?"CM":"");
+ printf("# %.2f %.2f diff %.2f ",m[i].stsec/1000.0,m[i].edsec/1000.0,m[i].diffs/1000.0);
+ if (m[i].cmflg==1) printf("CM\n");
+ else printf("%s\n",m[i].fixparam?m[i].fixparam:"");
+
//本編開始位置をマーク
if ((m[i].cmflg==0)&&(honstart==0)) {
honstart=1;
if (i==0) h[hcnt].stsec = 0;
- else h[hcnt].stsec = m[i-1].edsec+(defmuon*0.5);
+ else h[hcnt].stsec = m[i-1].edsec+(defmuon*0.5) + m[i].stsecfix;
}
else {
//終了位置をマーク
if ((m[i].cmflg==1)&&(honstart==1)) {
honstart=0;
//h[hcnt].edsec = m[i-1].stsec;
- h[hcnt].edsec = checkMP4RAP(m[i-1].stsec,m[i-1].edsec);
+ h[hcnt].edsec = checkMP4RAP(m[i-1].stsec,m[i-1].edsec) + m[i-1].edsecfix;
totalsec += h[hcnt].edsec - h[hcnt].stsec;
hcnt++;
}
}
}
if (honstart==1) {
- h[hcnt].edsec = checkMP4RAP(m[i-1].stsec,m[i-1].edsec);
+ h[hcnt].edsec = checkMP4RAP(m[i-1].stsec,m[i-1].edsec) + m[i-1].edsecfix;
totalsec += h[hcnt].edsec - h[hcnt].stsec;
hcnt++;
}
cmdlist = tclistnew();
tflist = tclistnew();
+ if (wkfilename) {
+ asprintf(&cptr,"rm -f '%s.split.log'",wkfilename);
+ tclistpush2(cmdlist,cptr);
+ free(cptr);
+ }
for(i=0;i<hcnt;i++) {
if (wkfilename) {
asprintf(&tfptr,"%s.%d%s",wkfilename,i,noaudioencode?".mp4":"");
- asprintf(&cptr,"%s -splitx %.2f:%.2f %s -out %s",MP4BOXCMD,h[i].stsec/1000.0,h[i].edsec/1000.0,wkfilename,tfptr);
+ asprintf(&cptr,"%s -quiet -noprog -splitx %.2f:%.2f '%s' -out '%s' >> '%s.split.log'",MP4BOXCMD,h[i].stsec/1000.0,h[i].edsec/1000.0,wkfilename,tfptr,wkfilename);
tclistpush2(cmdlist,cptr);
tclistpush2(tflist,tfptr);
free(tfptr);
if (!noaudioencode) {
asprintf(&tfptr,"%s.%d.wav",wkfilename,i);
- asprintf(&cptr,"%s -v 0 -i %s.%d -vn %s",FFMPEGCMD,wkfilename,i,tfptr);
+ if (FAADCMD)
+ asprintf(&cptr,"%s -d -q -o '%s' '%s.%d' ",FAADCMD,tfptr,wkfilename,i);
+ else
+ asprintf(&cptr,"%s -v 0 -i '%s.%d' -vn '%s'",FFMPEGCMD,wkfilename,i,tfptr);
tclistpush2(cmdlist,cptr);
tclistpush2(tflist,tfptr);
free(tfptr);
free(cptr);
asprintf(&tfptr,"%s.%d.mp4",wkfilename,i);
- asprintf(&cptr,"%s -v 0 -i %s.%d -an -vcodec copy %s",FFMPEGCMD,wkfilename,i,tfptr);
+ asprintf(&cptr,"%s -v 0 -i '%s.%d' -an -vcodec copy '%s'",FFMPEGCMD,wkfilename,i,tfptr);
tclistpush2(cmdlist,cptr);
tclistpush2(tflist,tfptr);
free(tfptr);
}
}
else {
- asprintf(&cptr,"# %s -splitx %.2f:%.2f ",MP4BOXCMD,h[i].stsec/1000.0,h[i].edsec/1000.0);
+ asprintf(&cptr,"# %s -quiet -noprog -splitx %.2f:%.2f ",MP4BOXCMD,h[i].stsec/1000.0,h[i].edsec/1000.0);
tclistpush2(cmdlist,cptr);
}
}
if (wkfilename) {
if (!noaudioencode) {
- asprintf(&cptr2,"%s ",SOXCMD);
+ asprintf(&cptr2,"%s --norm ",SOXCMD);
for(i=0;i<hcnt;i++) {
asprintf(&tfptr,"%s.%d.wav",wkfilename,i);
- asprintf(&cptr,"%s %s ",cptr2,tfptr);
+ asprintf(&cptr,"%s '%s' ",cptr2,tfptr);
free(cptr2);
cptr2=cptr;
tclistpush2(tflist,tfptr);
free(tfptr);
}
asprintf(&tfptr,"%s.wav",wkfilename);
- asprintf(&cptr,"%s %s",cptr2,tfptr);
+ asprintf(&cptr,"%s '%s'",cptr2,tfptr);
free(cptr2);
tclistpush2(cmdlist,cptr);
tclistpush2(tflist,tfptr);
free(tfptr);
asprintf(&tfptr,"%s.aac",wkfilename);
- asprintf(&cptr,"%s %s.wav %s 60",AACENCCMD,wkfilename,tfptr);
+ asprintf(&cptr,AACENCOPT,AACENCCMD,wkfilename,tfptr);
tclistpush2(cmdlist,cptr);
free(cptr);
tclistpush2(tflist,tfptr);
free(tfptr);
}
- //再チェックの場合-new.mp4ファイルを削除する
- if (txtrecheck) {
- asprintf(&cptr,"rm -f %s-new.mp4",wkfilename);
- tclistpush2(cmdlist,cptr);
- free(cptr);
- }
- asprintf(&cptr2,"%s",MP4BOXCMD);
+ //ファイル名-new.mp4ファイルを削除する
+ asprintf(&cptr,"rm -f '%s-new.mp4'",wkfilename);
+ tclistpush2(cmdlist,cptr);
+ free(cptr);
+
+ asprintf(&cptr2,"%s -quiet -noprog ",MP4BOXCMD);
for(i=0;i<hcnt;i++) {
- asprintf(&cptr,"%s -cat %s.%d.mp4 ",cptr2,wkfilename,i);
+ asprintf(&cptr,"%s -cat '%s.%d.mp4' ",cptr2,wkfilename,i);
free(cptr2);
cptr2=cptr;
}
- asprintf(&cptr,"%s %s-new.mp4",cptr2,wkfilename);
+ asprintf(&cptr,"%s '%s-new.mp4'",cptr2,wkfilename);
tclistpush2(cmdlist,cptr);
free(cptr);
if (!noaudioencode) {
- asprintf(&cptr,"%s -add %s.aac %s-new.mp4",MP4BOXCMD,wkfilename,wkfilename);
+ asprintf(&cptr,"%s -quiet -noprog -add '%s.aac' '%s-new.mp4'",MP4BOXCMD,wkfilename,wkfilename);
tclistpush2(cmdlist,cptr);
}
+ /* wkfilename.mp4.assファイルがあったらfixassを実施 */
+ asprintf(&cptr,"%s.ass",wkfilename);
+ fp = fopen(cptr,"r");
+ if (fp) {
+ free(cptr);
+ fclose(fp);
+ asprintf(&cptr,"%s '%s' > '%s.fix.ass'",FIXASS,wkfilename,wkfilename);
+ tclistpush2(cmdlist,cptr);
+ free(cptr);
+ }
+ else {
+ free(cptr);
+ }
for(i=0;i<tclistnum(tflist);i++) {
- asprintf(&cptr,"rm -f %s",tclistval2(tflist,i));
+ asprintf(&cptr,"rm -f '%s'",tclistval2(tflist,i));
tclistpush2(cmdlist,cptr);
free(cptr);
}
if (thumb) {
pre=0;
for(i=0;i<mcnt;i++) {
- asprintf(&cptr,"mplayer -ss %.2f -frames 1 -vo png %s ; mv 00000001.png %s-%d.png",(pre + (m[i].stsec-pre)/2)/1000.0,wkfilename,wkfilename,i);
+ asprintf(&cptr,"%s -ao null -ss %.2f -frames 1 -vo png:z=9 '%s' ; mv 00000001.png '%s-%d.png'",MPLAYERCMD,(pre + (m[i].stsec-pre)/2)/1000.0,wkfilename,wkfilename,i);
tclistpush2(cmdlist,cptr);
pre = m[i].stsec;
}
}
for (i=0;i<tclistnum(cmdlist);i++) {
- if (cmdexecute) {
+ if (cmdexecute && wkfilename) {
FILE *pp;
char pbuf[1024];
pp = popen(tclistval2(cmdlist,i),"r");
- if (pp==NULL) {printf("cmdfail %s\n",tclistval2(cmdlist,i));continue;}
+ if (pp==NULL) {continue;}
while(fgets(pbuf,1024,pp)!=NULL){
}
pclose(pp);
m[cnt].edsec = (int)(atof(wk2)*1000.0);
m[cnt].diffs = (int)(atof(wk3)*1000.0);
if (strstr(wk4,"CM")) m[cnt].cmflg=1;
- else m[cnt].cmflg=0;
+ else {
+ m[cnt].cmflg=0;
+ /* CMカット位置の調整パラメータ
+ -0.1, (開始位置を-0.1秒ずらす、終了位置はそのまま)
+ ,7 (開始位置そのまま、終了位置は7フレームずらす)
+ -0.5,10 (開始位置を-0.5秒、終了位置を10フレームずらす)
+ 開始位置パラメータが有効なのはCMの直後
+ 終了位置パラメータが有効なのは次がCMの場合のみとする。
+ */
+ if (strlen(wk4)>0) {
+ m[cnt].fixparam = strdup(wk4);
+ TCLIST *t = tcstrsplit(wk4,",");
+ if (tclistnum(t)==2) {
+ m[cnt].edsecfix = atoi(tclistval2(t,1))*33;
+ }
+ if (tclistnum(t)>=1) {
+ m[cnt].stsecfix = (int)(atof(tclistval2(t,0))*1000.0);
+ }
+ }
+ }
m[cnt].honpen = 0;
cnt++;
}
}
+ if (checkcomplete > 0) {
+ return cmpinfo(cnt);
+ }
txtrecheck=1;
return dumpinfo(cnt);
}
readed=max=totalsec=kankaku=mcnt=0;
+ memset(m,sizeof(m),0);
+ memset(h,sizeof(h),0);
peak=0;
muonstartsec=-1;
loop=1;
int i,ch;
FILE *f,*p;
int ret;
- char *tmpenv;
+ char *tmpenv,*argv0;
ret = -1;
- while ((ch = getopt(argc, argv, "adtxb:m:v:")) != -1){
+ argv0 = argv[0];
+ while ((ch = getopt(argc, argv, "agdtxb:m:v:c:")) != -1){
switch (ch){
case 'a':
noaudioencode=1;
break;
+ case 'g':
+ basets=1;
+ break;
case 'd':
verbose=1;
break;
case 'x':
cmdexecute=1;
break;
+ case 'c':
+ checkcomplete=atoi(optarg);
+ if (checkcomplete <= 0 && checkcomplete > 2) usage(argv0);
+ break;
default:
- usage();
+ usage(argv0);
}
}
argc -= optind;
argv += optind;
if (argc != 1) {
- usage();
+ usage(argv0);
return 0;
}
if (tmpenv=getenv("FFMPEG")) FFMPEGCMD=tmpenv;
if (tmpenv=getenv("MP4BOX")) MP4BOXCMD=tmpenv;
if (tmpenv=getenv("MP4BOXCMDRAPSTR")) MP4BOXCMDRAPSTR=tmpenv;
if (tmpenv=getenv("AACENC")) AACENCCMD=tmpenv;
- if (tmpenv=getenv("MPLAYERCMD")) MPLAYERCMD=tmpenv;
+ if (tmpenv=getenv("AACENCPOT")) AACENCOPT=tmpenv;
+ if (tmpenv=getenv("MPLAYER")) MPLAYERCMD=tmpenv;
+ if (tmpenv=getenv("FAADCMD")) FAADCMD=tmpenv;
+#ifdef DEBUG
+ if ((FAADCMD) && (tmpenv=getenv("FORCEFFMPEGCMD"))) FAADCMD = NULL;
+#endif
ret=0;
p=NULL;