OSDN Git Service

add no audio encode checkbox
[cmcheckwave/cmcheckwave.git] / cmcheckwave.c
index b3bf322..ca13b2b 100644 (file)
@@ -12,7 +12,19 @@ Usage: cmcheckwave filename.wav
 #include <unistd.h>
 #include <assert.h>
 
-static void usage(void){
+#include "tclist.h"
+
+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);
 }
 
@@ -46,6 +58,10 @@ typedef struct {
        int  diffs;
        char cmflg;
        char honpen;
+       int  peak;
+       int  stsecfix;
+       int  edsecfix;
+       char *fixparam;
 }muonst;
 
 static muonst m[1000];
@@ -55,11 +71,79 @@ static int noaudioencode=0;
 static char *wkfilename=NULL;
 static int defmuon=250;
 static int defmax=9;
-
-static char *MP4BOXCMD="/usr/local/bin/MP4Box -quiet -noprog";
+static int thumb=0;
+static int txtrecheck=0;
+static int cmdexecute=0;
+static int checkcomplete=0;
+static int basets=0;
+
+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);
+       rewind(f);
+       if (!strstr(readbuf+4,"ftypisom")) {
+               return NULL;
+       }
+       // mp4ファイルだったら、ffmpegでwaveに変換し読み込む。
+       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);
+       wkfilename = strdup(filename);
+       return pp;
+}
+
+FILE *openpipeffmpeg(char *filename)
+{
+       char cmdbuf[1024];
+       FILE *pp;
+
+
+
+}
 
 int checkMP4RAP(int stsec,int edsec)
 {
@@ -70,14 +154,14 @@ int checkMP4RAP(int stsec,int edsec)
 
        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");
        if (pp == NULL) return stsec;
        while(fgets(pbuf,1024,pp)!=NULL){
-               if (strstr(pbuf,"Adjusting chunk start time to previous random access at ")) {
-                       sscanf(pbuf+56,"%f",&rap);
+               if (strstr(pbuf,MP4BOXCMDRAPSTR)) {
+                       sscanf(pbuf+strlen(MP4BOXCMDRAPSTR),"%f",&rap);
                        //TODO rapはCM開始フレームの秒数なのでちょっと戻す。
                        //     フレームレートとか調べないとだめだな・・・
                        rap = rap - 0.04;
@@ -88,10 +172,93 @@ int checkMP4RAP(int stsec,int edsec)
        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;
-       int i;
+       int i,pre;
+       char *cptr,*cptr2,*tfptr;
+       TCLIST *cmdlist;
+       TCLIST *tflist;
+       FILE *fp;
 
        honstart=0;
        hcnt=0;
@@ -99,64 +266,165 @@ int dumpinfo(int mcnt)
        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++;
        }
 
        printf("# total %.2f\n\n",totalsec/1000.0);
 
+       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) {
-                       printf("%s -splitx %.2f:%.2f %s -out %s.%d%s\n",MP4BOXCMD,h[i].stsec/1000.0,h[i].edsec/1000.0,wkfilename,wkfilename,i,noaudioencode?".mp4":"");
+                       asprintf(&tfptr,"%s.%d%s",wkfilename,i,noaudioencode?".mp4":"");
+                       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);
+                       free(cptr);
+
                        if (!noaudioencode) {
-                               printf("%s -v 0 -i %s.%d -vn %s.%d.wav\n",FFMPEGCMD,wkfilename,i,wkfilename,i);
-                               printf("%s -v 0 -i %s.%d -an -vcodec copy %s.%d.mp4\n",FFMPEGCMD,wkfilename,i,wkfilename,i);
+                               asprintf(&tfptr,"%s.%d.wav",wkfilename,i);
+
+                               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);
+                               tclistpush2(cmdlist,cptr);
+                               tclistpush2(tflist,tfptr);
+                               free(tfptr);
+                               free(cptr);
                        }
                }
                else {
-                       printf("# %s -splitx %.2f:%.2f \n",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) {
-                       printf("%s ",SOXCMD);
+                       asprintf(&cptr2,"%s --norm ",SOXCMD);
                        for(i=0;i<hcnt;i++) {
-                               printf(" %s.%d.wav ",wkfilename,i);
+                               asprintf(&tfptr,"%s.%d.wav",wkfilename,i);
+                               asprintf(&cptr,"%s '%s' ",cptr2,tfptr);
+                               free(cptr2);
+                               cptr2=cptr;
+                               tclistpush2(tflist,tfptr);
+                               free(tfptr);
                        }
-                       printf(" %s.wav\n",wkfilename);
-                       printf("%s %s.wav %s.aac 60\n",AACENCCMD,wkfilename,wkfilename);
+                       asprintf(&tfptr,"%s.wav",wkfilename);
+                       asprintf(&cptr,"%s '%s'",cptr2,tfptr);
+                       free(cptr2);
+                       tclistpush2(cmdlist,cptr);
+                       tclistpush2(tflist,tfptr);
+                       free(tfptr);
+
+                       asprintf(&tfptr,"%s.aac",wkfilename);
+                       asprintf(&cptr,AACENCOPT,AACENCCMD,wkfilename,tfptr);
+                       tclistpush2(cmdlist,cptr);
+                       free(cptr);
+                       tclistpush2(tflist,tfptr);
+                       free(tfptr);
                }
-               printf("%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++) {
-                       printf(" -cat %s.%d.mp4 ",wkfilename,i);
+                       asprintf(&cptr,"%s -cat '%s.%d.mp4' ",cptr2,wkfilename,i);
+                       free(cptr2);
+                       cptr2=cptr;
                }
-               printf(" %s-new.mp4\n",wkfilename);
+               asprintf(&cptr,"%s '%s-new.mp4'",cptr2,wkfilename);
+               tclistpush2(cmdlist,cptr);
+               free(cptr);
 
-               if (!noaudioencode)
-                       printf("%s -add %s.aac %s-new.mp4\n",MP4BOXCMD,wkfilename,wkfilename);
+               if (!noaudioencode) {
+                       asprintf(&cptr,"%s -quiet -noprog -add '%s.aac' '%s-new.mp4'",MP4BOXCMD,wkfilename,wkfilename);
+                       tclistpush2(cmdlist,cptr);
+               }
 
-               printf("rm -f %s.*\n\n",wkfilename);
+               /* 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));
+                       tclistpush2(cmdlist,cptr);
+                       free(cptr);
+               }
+
+               if (thumb) {
+                       pre=0;
+                       for(i=0;i<mcnt;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 && wkfilename) {
+                       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 rechecktext(FILE *f)
@@ -198,12 +466,35 @@ int rechecktext(FILE *f)
                        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);
 
 
@@ -223,13 +514,14 @@ int cmcheckwave(FILE *f)
        unsigned char *readbuf;
        int honstart;
        int cmwork;
-
+       int peak;
 
        if (memcmp(get_bytes(f, 4), "RIFF", 4) != 0) {
                //   fprintf(stderr, "Not a 'RIFF' format\n");
                return -1;
        }
-       fprintf(stderr, "[RIFF] (%lu bytes)\n", get_ulong(f));
+       //fprintf(stderr, "[RIFF] (%lu bytes)\n", get_ulong(f));
+       get_ulong(f);
        if (memcmp(get_bytes(f, 8), "WAVEfmt ", 8) != 0) {
                // fprintf(stderr, "Not a 'WAVEfmt ' format\n");
                return -1;
@@ -260,6 +552,9 @@ int cmcheckwave(FILE *f)
        }
 
        readed=max=totalsec=kankaku=mcnt=0;
+       memset(m,sizeof(m),0);
+       memset(h,sizeof(h),0);
+       peak=0;
        muonstartsec=-1;
        loop=1;
        readbuf=malloc(4096*1000);
@@ -280,6 +575,7 @@ int cmcheckwave(FILE *f)
                                        readbufsz+=2;
                                }
                                if (x > max) max = x;
+                               if (x > peak) peak = x;
                                //printf("%d", x);
                                //if (i != channels - 1) printf("\t");
                        }
@@ -309,7 +605,10 @@ int cmcheckwave(FILE *f)
                                                        if ((diffs >  59.5) && (diffs < 60.5)) m[mcnt].cmflg=1;
 
                                                        kankaku=totalsec;
+                                                       m[mcnt].peak=peak;
                                                        mcnt++;
+
+                                                       peak=0;
                                                }
                                                muonstartsec=-1;
                                        }
@@ -323,23 +622,23 @@ int cmcheckwave(FILE *f)
                //本編前CMチェック
                if ((m[0].cmflg==0) && (m[0].diffs < 15000))
                        m[0].cmflg=1;
-               // 最終CMチェック
-               if ((m[mcnt-1].cmflg==0) && (m[mcnt-1].diffs < 15000))
-                       m[mcnt-1].cmflg=1;
                //細切れCMのたしこみ
                for(i=1;i<mcnt-1;i++) {
                        // 本編で31秒以下が連続だったら、次の31秒以上の本編もしくはCMまでの時間をチェック
+                       // 足しこみは61秒まで
+                       // TODO 28+32で60秒CMとかいうのがあるどうするのがいいだろうか・・・
                        if (m[i].cmflg==0 && m[i].diffs < 31000  && m[i+1].cmflg==0 && m[i+1].diffs < 31000) {
                                cmwork=0;
-                               for(j=i;j<mcnt-1;j++) {
+                               for(j=i;j<mcnt;j++) {
                                        if (m[j].cmflg==1) break;
                                        if (m[j].diffs > 31000) break;
+                                       if (cmwork + m[j].diffs > 61000) break;
                                        cmwork = cmwork + m[j].diffs;
                                }
                                //合計時間を15秒で割ってcm時間っぽいならばCMとする。
                                // TODO 30(15)秒以下の条件付けがいる?60秒どうする?
                                if (cmwork%15000>14500 || cmwork%15000<500) {
-                                       for(j=i;j<mcnt-1;j++) {
+                                       for(j=i;j<mcnt;j++) {
                                                if (m[j].cmflg==1) break;
                                                if (m[j].diffs > 31000) break;
                                                m[j].cmflg=1;
@@ -348,6 +647,9 @@ int cmcheckwave(FILE *f)
                        }
 
                }
+               // 最終CMチェック
+               if ((m[mcnt-1].cmflg==0) && (m[mcnt-1].diffs < 15000))
+                       m[mcnt-1].cmflg=1;
                //短い本編・提供などの処理
                for(i=1;i<mcnt-1;i++) {
                        //本編で46秒以下かつ、前後がCMの場合CM14-16,29-31,44-46秒でもCMとする。
@@ -363,6 +665,11 @@ int cmcheckwave(FILE *f)
                                if ((m[i].diffs > 9500) && (m[i].diffs < 10500)) m[i-1].cmflg=0;
                                if ((m[i].diffs > 4500) && (m[i].diffs < 5500)) m[i-1].cmflg=0;
                        }
+                       // TODO 前後が本編で単独でCMの場合は本編とする?
+                       // 46秒以下のチェックも?
+                       // if (m[i].cmflg==1 && m[i-1].cmflg==0 && m[i+1].cmflg==0) {
+                       //      m[i].cmflg=0;
+                       // }
                }
 
        }
@@ -374,16 +681,20 @@ int main(int argc, char *argv[])
        extern char *optarg;
        extern int optind, opterr;
        int i,ch;
-       FILE *f;
+       FILE *f,*p;
        int ret;
-       char *tmpenv;
+       char *tmpenv,*argv0;
        ret = -1;
 
-       while ((ch = getopt(argc, argv, "adb: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;
@@ -396,33 +707,59 @@ int main(int argc, char *argv[])
                        case 'v':
                                defmax=atoi(optarg);
                                break;
+                       case 't':
+                               thumb=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("SOX")) SOXCMD=tmpenv;
        if (tmpenv=getenv("MP4BOX")) MP4BOXCMD=tmpenv;
+       if (tmpenv=getenv("MP4BOXCMDRAPSTR")) MP4BOXCMDRAPSTR=tmpenv;
        if (tmpenv=getenv("AACENC")) AACENCCMD=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;
        if (strcmp(argv[0],"-")==0)
                f = stdin;
-       else
+       else {
                f = fopen(argv[0],"rb");
-       if (f) {
-               ret = cmcheckwave(f);
-               // -1 のときはテキストとして再チェック
-               if (ret == -1) rechecktext(f);
-               fclose(f);
+               if (f) {
+                       p = checkMP4(f,argv[0]);
+               }
+               else
+                       return -1;
        }
+
+       if (p)  ret = cmcheckwave(p);
+       else    ret = cmcheckwave(f);
+       // -1 のときはテキストとして再チェック
+       if (ret == -1) rechecktext(f);
+       if (p) pclose(p);
+       else fclose(f);
+
        return ret;
 }