LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   script to play video file as needed (https://www.linuxquestions.org/questions/linux-newbie-8/script-to-play-video-file-as-needed-949125/)

sumeet inani 06-07-2012 09:39 PM

script to play video file as needed
 
hi ,
I have slitaz 3.0
Here mplayer does not support xv video output (must be due to needs of my xfx card ).
Anyway I can play using x11 but here scaling ain't available i.e pressing 'f' does not expand video to cover the whole screen.
I have an idea as follows
I will run 'my-play filename'
my-play is a script like
Code:

ffmpeg -i <input-to-my-play>
Is it possible to get the directory from where 'my-play' was run
OR
will 'ffmpeg -i' run from same directory as input file?

I thought about processing output of ffmpeg to extract 'number x number' because that is the video resolution .
But seems 'ffmpeg -i <file>' gives error output so
"ffmpeg -i <file> | grep 'something'"
just gives whole error output
i.e

       
Quote:

       
       
               
       
       

                       

                       
                                FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --prefix=/usr --enable-gpl --arch=i486 --cpu=i486 --enable-shared --enable-small --enable-pthreads --enable-postproc --disable-mmx --disable-mmx2 --disable-ssse3
  libavutil    49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat  52.31. 0 / 52.31. 0
  libavdevice  52. 1. 0 / 52. 1. 0
  libpostproc  51. 2. 0 / 51. 2. 0
  built on Feb 17 2010 00:10:29, gcc: 4.4.1

Seems stream 1 codec frame rate differs from container frame rate: 50.00 (50/1) -> 25.00 (25/1)
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Jan Ove Waldner vs. Ma lin.mp4':
  Duration: 00:04:02.56, start: 0.000000, bitrate: 629 kb/s
    Stream #0.0(und): Audio: aac, 44100 Hz, stereo, s16
    Stream #0.1(und): Video: h264, yuv420p, 480x360, 25 tbr, 25 tbn, 50 tbc
At least one output file must be specified
                       
                       

               

If I am able to get x resolution of video file then I have to calculate
800\<x-resolution> = integer.fraction
<new-x-resolution> = integer multiply original-x
<new-y-resolution> = integer multiply original-y
I will run
mplayer -vo x11 -vf scale=<new-x-resolution>:<new-y-resolution>


rigor 06-08-2012 04:38 PM

I was able to redirect the standard error output like this,
by specifying /dev/null as the output file for the conversation.

Code:

ffmpeg -i MVI_0286.AVI  /dev/null  2>out.stderr
then

Code:

fgrep -i Stream out.stderr | fgrep Video
outputs, in my case:

Code:

Stream #0:0: Video: mjpeg (MJPG / 0x47504A4D), yuvj422p, 320x240, 15 tbr, 15 tbn, 15 tbc
so you could parse out the existing resolution.

sumeet inani 06-08-2012 09:08 PM

I thought . No one will reply .
I made a ragtag script which does my work
Here it is
You can suggest improvements (my questions are in blue below)
Code:

echo i have to process following file : $1
ffmpeg -i "$1"  2> ~/log.txt
xres=$(sed -n 's/.* \(\([0-9]*\)x[0-9]*\).*/\2/p' ~/log.txt)
yres=$(sed -n 's/.* \([0-9]*x\([0-9]*\)\).*/\2/p'  ~/log.txt)
echo x-resolution is $xres
echo y-resolution is $yres

       
Quote:

       
       
               
       
       

                       

                       
                                #let "zoomfactor = 1024/$xres"bash gives answer without decimal while I want to fill my monitor with video as much as possible
#zoomfactor=$(echo "scale =2;1024/$xres"| bc -q)Initially I thought of using bc but firstly i had to install it & secondly it reported output with as many decimal places as operand in multiplication .
Obviously zoomfactor had decimal places.

#newxres=$(echo "$zoomfactor*$xres;scale=1" | bc )ain't using bc for purpose
mentioned above

#newyres=$(echo $zoomfactor*$yres | bc -q)ain't using bc for purpose mentioned above
                       
                       

               

You can tell me if it is possible for bc to output 640x2.50 as 1600 only ?
zoomfactor=$(echo "1024 $xres" | awk '{printf "%f", $1 / $2}')
echo scaling will be $zoomfactor as per awk
newxres=$(echo "$zoomfactor $xres" | awk '{printf "%d", $1 * $2}')
newyres=$(echo "$zoomfactor $yres" | awk '{printf "%d", $1 * $2}')
echo new x-resolution is $newxres and new y-resolution is $newyres
mplayer -vo x11 "$1" -vf scale=$newxres:$newyres


sumeet inani 06-08-2012 10:39 PM

Now I would like to add more features like
Code:

$# to see number of arguments
then create a string (explicit_options) like "$2 $3 ..."
This way
I will run
mplayer -vo x11 -vf scale=$new-x-resolution:new-y-resolution explicit_options
This way if I mention subtitle file (like '-sub something.srt') then  it will be incorporated.

Further it would be great if my script can auto-detect subtitle file
For this I have thought (assuming I have just srt no .sub or any other format)
Code:

ls -1 *srt > ~/list.txt
take 1 line at a time
store it as string & compare it with $1 to calculate number of character matches .
The one with highest count is presumed corresponding subtitle file.
The command that gets run is
mplayer -vo x11 -vf scale=$new-x-resolution:new-y-resolution -sub <gueesed-srt-file> explicit_options


I was using ffmpeg because it is more widespread . ffprobe would have been alright , too .
Anyway I am past that . Thanks for suggestion .
now , I need help for adding more features to script as mentioned above .
Please suggest me how to do that ?

jschiwal 06-08-2012 10:41 PM

You could use ffprobe or MediaInfo to supply the size information. Also look at ffplay which has a -s XxY option.

sumeet inani 06-09-2012 08:54 AM

I don't know about bash scripting
Actually I intend to do following
Code:

result=$(ls -1 *srt | wc -l)
if result==0
{  echo "no subtitle file present"
  mplayer -vo x11 --adjusted x& y resolution --explicit-options given
}
else
{
ls -l *srt > ~/candidates.txt
for (i=1,greatest=0,suitable="";i<=result;i++)
    { array[i]= take another line from candidates.txt
      marks[i]=$(/usr/bin/compare-string array[i] $1)
      if(marks[i]>greatest)
      {        greatest=marks[i];
                suitable=array[i];
      }
    }
mplayer -vo x11 -sub $suitable --adjusted x& y resolution --explicit-options given
}

I can write & compile a c program which accepts two string & give integer feedback of number of character matches.

As you must have seen , I know little C programming .
I need help in doing above abstract method using bash scripting

sumeet inani 06-09-2012 09:30 PM

Finally , I wrote the script as follows

Code:

$ cat /usr/bin/sumplay

       
Quote:

       
       
               
       
       

                       

                       
                                #!/bin/sh
# what are we doing is wrwd
cd "$(dirname "$1")"
let yourmonitorx=1024
let yourmonitory=768
echo our current directory is $(pwd) > ~/trial/wrwd.txt
ls *srt > ~/trial/srt.txt
echo exit status is $? >> ~/trial/wrwd.txt
biggest_so_far=0
if [ $? -eq 0 ]
then
while read line; do
/usr/bin/guess "$1" "$line"
count=$?
if [ "$biggest_so_far" -le "$count" ]
then
        biggest_so_far=$count
        suitable=$line
fi
echo -e  match between \'$1\' and \'$line\' is $count >> ~/trial/wrwd.txt
done < ~/trial/srt.txt
echo -e I think suitable subtitle file is \'$suitable\' >> ~/trial/wrwd.txt
fi
echo i have to process following file : $1 >> ~/trial/wrwd.txt
ffmpeg -i "$1"  2> ~/trial/log.txt
xres=$(sed -n 's/.*Video: .* \(\([0-9]*\)x[0-9]*\).*/\2/p' ~/trial/log.txt)
yres=$(sed -n 's/.*Video: .* \([0-9]*x\([0-9]*\)\).*/\2/p'  ~/trial/log.txt)
echo x-resolution is $xres >> ~/trial/wrwd.txt
echo y-resolution is $yres >> ~/trial/wrwd.txt
zoomfactor=$(echo "$yourmonitorx $xres" | awk '{printf "%.2f", $1 / $2}')
echo scaling will be $zoomfactor as per awk >> ~/trial/wrwd.txt
newxres=$(echo "$zoomfactor $xres" | awk '{printf "%d", $1 * $2}')
newyres=$(echo "$zoomfactor $yres" | awk '{printf "%d", $1 * $2}')
bottomblackband=$(($yourmonitory-$newyres))
if [ "$newyres" -gt $yourmonitory ]
then
zoomfactor=$(echo "$yourmonitory $yres" | awk '{printf "%.2f", $1 / $2}')
newxres=$(echo "$zoomfactor $xres" | awk '{printf "%d", $1 * $2}')
newyres=$(echo "$zoomfactor $yres" | awk '{printf "%d", $1 * $2}')
bottomblackband=0
fi
echo new x-resolution is $newxres and new y-resolution is $newyres and bottomblackband is $bottomblackband >> ~/trial/wrwd.txt
if [ "$biggest_so_far" -gt 0 ]
then
echo WE ARE GOING TO RUN mplayer -vo x11 "$1" -vf scale=$newxres:$newyres,expand=0:-$bottomblackband:0:0 -sub "$suitable" >> ~/trial/wrwd.txt
mplayer -vo x11 "$1" -vf scale=$newxres:$newyres,expand=0:-$bottomblackband:0:0 -sub "$suitable"
else
echo NO SUITABLE SUBTITLE FILE WAS GUESSED >> ~/trial/wrwd.txt
echo WE ARE GOING TO RUN mplayer -vo x11 "$1" -vf scale=$newxres:$newyres,expand=0:-$bottomblackband:0:0  >> ~/trial/wrwd.txt
mplayer -vo x11 "$1" -vf scale=$newxres:$newyres,expand=0:-$bottomblackband:0:0
fi
                       
                       

               

guess is a binary compiled from

       
Quote:

       
       
               
       
       

                       

                       
                                #include<stdio.h>
#include<string.h>
int main(int argc, char *argv[])
{      int i,j,k,l,sum;
        char *src,*cdt;
        if(argc!=3)
        {      printf("\nImproper input since I got %d parameters\n",argc);
                return 1;
        }
        else
        {      src=argv[1];
                cdt=argv[2];
                //printf("\nargument I received are : ");
                for(i=1;i<argc;i++)
                {
                        //printf("\n%s",argv[i]);
                }
        }
        for(sum=0,i=97,j=65;i<=122;i++,j++)
        {      for(k=0,src=argv[1];*src!=0;src++)
                {      if((*src==i) || (*src==j))
                        {      //printf("\n%c found",*src);
                                k++;
                        }
                }
                if(k>0)
                {      printf("\n%d %c found in source",k,i);
                        for(l=0,cdt=argv[2];*cdt!=0;cdt++)
                        {      if((*cdt==i) || (*cdt==j))
                                {      //printf("\n%c found",*cdt);
                                l++;
                                }
                        }
                        printf("\n%d %c found in candidate",l,i);
                        if(l>k)
                                sum=sum+k;
                        else
                                sum=sum+l;
                }
        }
        for(i=48;i<=57;i++)
        {      for(k=0,src=argv[1];*src!=0;src++)
                {      if(*src==i)
                        {      //printf("\n%c found",*src);
                                k++;
                        }
                }
                if(k>0)
                {      printf("\n%d %c found in source",k,i);
                        for(l=0,cdt=argv[2];*cdt!=0;cdt++)
                        {      if(*cdt==i)
                                {      //printf("\n%c found",*cdt);
                                l++;
                                }
                        }
                        printf("\n%d %c found in candidate",l,i);
                        if(l>k)
                                sum=sum+k;
                        else
                                sum=sum+l;
                }
        }
//printf("\nMatch count is %d\n",sum);
return sum;
}
                       
                       

               



This has black band at bottom for subtitles too.

sumeet inani 06-10-2012 04:07 AM

I wanted to do the same in windows but unfortunately the filename passes to executable is in 8.3 format .So without full name of file cannot do.

sumeet inani 06-10-2012 11:14 AM

Got some breakthrough .
The full file name can be found out using
dir /b "<shortname>"
I have tried this in command.com & cmd.exe . There , it worked .
In my C program it does not . I don't know why ?

Code:

#include<stdio.h>
#include<process.h>
#include<string.h>
int main(int argc, char *argv[])
{        int i,j,dirresult;
        char command[512];
        FILE *log;
        log=fopen("c:\\log.txt","w");
        if(argc<2)
        {        fprintf(log,"\nI got %d arguments\n",argc);
                return 1;
        }
        fprintf(log,"\nI have received following arguments");
        for(i=0;i<argc;i++)
        {        fprintf(log,"\n(%d)%s",i+1,argv[i]);
        }
        strcat(command,"dir /b \"");
        strcat(command,argv[1]);
        strcat(command,"\" > c:\\dirlog.txt");
        fprintf(log,"\nwe are going to execute following command : %s",command);
        dirresult=system(command);
        //dirresult=system("dir /b > c:\\dirlog.txt");
        if(dirresult!=0)
                fprintf(log,"\nError in executing dir command");
        fclose(log);
        return 0;
}

I have windows xp .
If you can compile this into executable then you can try
<executable> C:\PROGRA~1
You will get log in c:\log.txt & c:\dirlog.txt

sumeet inani 06-14-2012 11:59 AM

Turns out I was using old borland c++ compiler version 3.0
I downloaded bcc 5.5 for free
Here is the source C program which when compiled gives an executable which can be added to registry key My computer\HKCR\*\shell\autosub\command . Assign default with c:\autosub.exe "%1"
Now I right click on any file & select autosub to play it with detected similiar srt file.
Code:

#include<stdio.h>
#include<process.h>
#include<string.h>
#define YES 1
#define NO 0
//dwhs=do we have sub , bsf=biggest so far,suitsub=suitable sub
char suitsub[256];
FILE *log;
int guess(char *cdt,char *src)
{        int i,j,k,l,sum;
        char *pointer;
        for(sum=0,i=97,j=65;i<=122;i++,j++)
        {        for(k=0,pointer=src;*pointer!=0;pointer++)
                {        if((*pointer==i) || (*pointer==j))
                        {        fprintf(log,"\n%c found in source",*pointer);
                                k++;
                        }
                }
                if(k>0)
                {        printf("\n%d %c found in source",k,i);
                        for(l=0,pointer=cdt;*pointer!=0;pointer++)
                        {        if((*pointer==i) || (*pointer==j))
                                {        fprintf(log,"\n%c found in candidate",*pointer);
                                l++;
                                }
                        }
                        printf("\n%d %c found in candidate",l,i);
                        if(l>k)
                                sum=sum+k;
                        else
                                sum=sum+l;
                }
        }
        for(i=48;i<=57;i++)
        {        for(k=0,pointer=src;*pointer!=0;pointer++)
                {        if(*pointer==i)
                        {        fprintf(log,"\n%c found in source",*pointer);
                                k++;
                        }
                }
                if(k>0)
                {        fprintf(log,"\n%d %c found in source",k,i);
                        for(l=0,pointer=cdt;*pointer!=0;pointer++)
                        {        if(*pointer==i)
                                {        fprintf(log,"\n%c found in candidate",*pointer);
                                l++;
                                }
                        }
                        printf("\n%d %c found in candidate",l,i);
                        if(l>k)
                                sum=sum+k;
                        else
                                sum=sum+l;
                }
        }
return sum;
}
void play(int dwhs,char *command,char *path)
{        int playresult;
        if(dwhs==NO)
        {        strcat(command,"kov \"");
                strcat(command,path);
                strcat(command,"\"");
                fprintf(log,"\n\nwe are going to execute following command : %s",command);
                playresult=system(command);
                        if(playresult!=0)
                                fprintf(log,"\nError in executing play command");
        }
        if(dwhs==YES)
        {        strcat(command,"kov \"");
                strcat(command,path);
                strcat(command,"\" -sub \"");
                strcat(command,suitsub);
                strcat(command,"\"");
                fprintf(log,"\n\nwe are going to execute following command : %s \n",command);
                playresult=system(command);
                        if(playresult!=0)
                                fprintf(log,"\nError in executing play command");
        }
}
int main(int argc, char *argv[])
{        int i,j,length,dirresult,matchcount,bsf=-1;
        FILE *subtitlefile;
        char command[512]="";
        char sub[256];
        char folder[512],file[256],path[768];
        log=fopen("c:/log.txt","w");
        if(argc<2)
        {        fprintf(log,"\nI got %d arguments\n",argc);
                return 1;
        }
        fprintf(log,"I have received following arguments");
        for(i=0;i<argc;i++)
        {        fprintf(log,"\n(%d)%s",i+1,argv[i]);
        }
        strcpy(path,argv[1]);
        strcpy(folder,argv[1]);
        for(i=strlen(argv[1])-1;folder[i]!='\\';i--)
                ;
        folder[i]=0;
        j=i;
        for(i=0;path[j]!=0;i++,j++)
                file[i]=path[j+1];
        file[i]=0;
        fprintf(log,"\n corresponding folder is %s",folder);
        fprintf(log,"\n video file is %s",file);
/*NOW THERE IS NO NEED , AS WE ARE ALREADY PRESENT IN THAT FOLDER so just list srt files*/
/*also dir "folder"/*srt OR  dir "folder/"*srt does not work*/
        for(i=0;path[i]!=0;i++)
                if(path[i]=='\\')
                        path[i]='/';
        /*strcat(command,"dir \"");
        strcat(command,folder);
        strcat(command,"\"/*srt /b > c:/dirlog.txt");
        dirresult=system(command);*/
        dirresult=system("dir  *srt /b > c:/dirlog.txt");
        if(dirresult!=0)
        {        fprintf(log,"\nDid not find subtitle file");
                play(NO,command,path);
        }
        else
        {
                subtitlefile=fopen("c:/dirlog.txt","r");
                while ( fgets ( sub, 255, subtitlefile ) != NULL )
                {        length=strlen(sub);
                        //fprintf(log,"\nLast characters of subtitle file are %d=%c , %d=%c , %d=%c",sub[length-1],sub[length-1],sub[length-2],sub[length-2],sub[length-3],sub[length-3]); # we did this because the last character was found to be \n
                        sub[length-1]=0;
                        fprintf(log,"\n\nwe just read \"%s\" ",sub);
                        matchcount=guess(sub,file);
                        fprintf(log,"\nThe matchcount has been %d\n",matchcount);
                        if(bsf<matchcount)
                                {        bsf=matchcount;
                                        strcpy(suitsub,sub);
                                }
                }
                fclose(subtitlefile);
                play(YES,command,path);
        }
        fclose(log);
        return 0;
}

Please note that kov points to my standalone kovensky build of mplayer file present in PATH.

414N 06-14-2012 01:09 PM

Can't you just use the -zoom mplayer option when using -vo x11? It should scale the video when in fullscreen mode without the need to specify the parameters of a scale filter.
Why can't you use xv?

sumeet inani 06-14-2012 11:25 PM

I tried it . It does not scale the image but just surrounds video on original resolution with black band. Slitaz is a tiny distro , it did not had drivers for my xfx card.

This thread started as need for slitaz & expanded to autodetecting subtitle file alongwith doing same on windows.
I digressed .

414N 06-15-2012 02:46 AM

Quote:

Originally Posted by sumeet inani (Post 4703715)
I tried it . It does not scale the image but just surrounds video on original resolution with black band. Slitaz is a tiny distro , it did not had drivers for my xfx card.

Weird... I tried it with a random movie and it successfully scales the video when activating fullscreen mode with the F key. Maybe you're using an ancient mplayer version?

sumeet inani 06-16-2012 03:28 AM

to 414N
You were write the first time with x11 video output & zoom option pressing f gets full screen scaling .
Now I realize.
Thank You.

I have fairly recent mplayer (from packages dvd of my slitaz)
Code:

MPlayer SVN-r30817-4.4.1 (C) 2000-2010 MPlayer Team
MMX supported but disabled
MMX2 supported but disabled
SSE supported but disabled
SSE2 supported but disabled
3DNow supported but disabled
3DNowExt supported but disabled

Currently I prefer repository.
Anyway , the binary does not play webm rest formats (eg. mkv,3gp,flv,mp4,avi) are fine.

I wish there was a portable binary of mplayer with dependent libraries etc. extracted in same folder. In windows I use kovensky build which is just a single file with everything present in it.

414N 06-16-2012 07:19 AM

You could always cook a slitaz package using tazwok.
First install slitaz-toolchain:
Code:

tazpkg get-install slitaz-toolchain
then you should clone the mercurial cookbook repository with
Code:

hg clone http://hg.slitaz.org/wok/ /home/slitaz/wok
provided you DON'T have personal receipts in there (/home/slitaz/wok).
You should now be able to cook mplayer 1.1 with
Code:

tazwok cook mplayer
If the cooking fails because the source cannot be extracted (invalid gzip magic), please edit /usr/bin/tazwok with your favorite text editor at line 337: you need to remove the z option to the tar command line, rendering it as:
Code:

tar xf [...]
.


All times are GMT -5. The time now is 07:01 PM.