How to make a movie constituted of image loops and audio?
Yuan Fang
I've wrote a procedure according to the Igor example FM Modulation Movie to make a movie constituted of image loops and audio. The experiment, procedure and pictures for the movie are in the attachment.
Macro MakeMovie(nframes,fRate,wAudio)
Variable nframes=NumVarOrDefault("gnframes",10)
Variable fRate=NumVarOrDefault("gwFPS",30)
Variable wAudio=NumVarOrDefault("gwAudio",2)
Prompt nframes,"Number of movie frames"
Prompt fRate,"Frame rate"
Prompt wAudio,"Sound:",popup "Off;On"
Variable/G gnframes= nframes
Variable/G gwFPS= fRate
Variable/G gwAudio= wAudio
DoMakeMovie(nframes,gwFPS,wAudio-1)
end
// returns error flag
Function ValidatePath()
PathInfo moviesPath
if( V_Flag==0 )
NewPath/o/Q moviesPath, SpecialDirPath("Igor Pro User Files", 0, 0, 0 )
if( V_Flag != 0 )
return 1 // abort or failure
endif
endif
return 0
End
Function DoMakeMovie(nframes,fRate,wAudio)
Variable nframes,fRate,wAudio
wave scar
Execute/Q "SetIgorOption VerboseMode=2"
newpath/o IgorSpace, "F:"
ValidatePath()
String fName= "sampleMovie"
String fExtension= ".mp4"
Variable isMac= CmpStr(IgorInfo(2),"Macintosh") == 0
Make/O/W/N=( 963332/fRate,2) yuanAudio
SetScale/P x,0,20/ 963332,"s" yuanAudio
variable i=0
do
int a=mod(i,4)
string nextImage = "pict"+num2str(a+1)+".bmp"
imageload /O/P=IgorSpace /T=bmp nextimage
duplicate/o $nextimage,w
redimension/n=(259,183,-1) w
newimage /n=season/s=0 w
if(i==0)
if( wAudio)
fName += "Audio"
NewMovie/cf=1/O/F=(fRate)/P=moviesPath/S=yuanAudio as fName+fExtension
else
NewMovie/cf=1/O/F=(fRate)/P=moviesPath as fName+fExtension
endif
if( V_Flag!=0 )
Print "OpenMovie failed, err= ",V_Flag
return 0 // probably canceled
endif
endif
doupdate
AddMovieFrame
killwindow season
killwaves $nextimage
if( V_Flag!=0 )
Print "Add movie frame failed, err= ",V_Flag,", frame ",i
if( isMac && wAudio )
Print "Specifing sound may not work on Mac"
endif
break
endif
i += 1
while(i<nframes)
if( wAudio )
yuanAudio= scar[100000+p]
AddMovieAudio/Z yuanAudio
if( V_Flag!=0 )
Print "Add movie audio failed, err= ",V_Flag
endif
endif
CloseMovie/Z
if( V_Flag!=0 )
Print "Close movie failed, err= ",V_Flag
endif
Sleep/S 1 // without this, Mac sometimes gives a file not a movie error; DoUpdate did not help
PlayMovie/P=moviesPath as fName+fExtension
end
Variable nframes=NumVarOrDefault("gnframes",10)
Variable fRate=NumVarOrDefault("gwFPS",30)
Variable wAudio=NumVarOrDefault("gwAudio",2)
Prompt nframes,"Number of movie frames"
Prompt fRate,"Frame rate"
Prompt wAudio,"Sound:",popup "Off;On"
Variable/G gnframes= nframes
Variable/G gwFPS= fRate
Variable/G gwAudio= wAudio
DoMakeMovie(nframes,gwFPS,wAudio-1)
end
// returns error flag
Function ValidatePath()
PathInfo moviesPath
if( V_Flag==0 )
NewPath/o/Q moviesPath, SpecialDirPath("Igor Pro User Files", 0, 0, 0 )
if( V_Flag != 0 )
return 1 // abort or failure
endif
endif
return 0
End
Function DoMakeMovie(nframes,fRate,wAudio)
Variable nframes,fRate,wAudio
wave scar
Execute/Q "SetIgorOption VerboseMode=2"
newpath/o IgorSpace, "F:"
ValidatePath()
String fName= "sampleMovie"
String fExtension= ".mp4"
Variable isMac= CmpStr(IgorInfo(2),"Macintosh") == 0
Make/O/W/N=( 963332/fRate,2) yuanAudio
SetScale/P x,0,20/ 963332,"s" yuanAudio
variable i=0
do
int a=mod(i,4)
string nextImage = "pict"+num2str(a+1)+".bmp"
imageload /O/P=IgorSpace /T=bmp nextimage
duplicate/o $nextimage,w
redimension/n=(259,183,-1) w
newimage /n=season/s=0 w
if(i==0)
if( wAudio)
fName += "Audio"
NewMovie/cf=1/O/F=(fRate)/P=moviesPath/S=yuanAudio as fName+fExtension
else
NewMovie/cf=1/O/F=(fRate)/P=moviesPath as fName+fExtension
endif
if( V_Flag!=0 )
Print "OpenMovie failed, err= ",V_Flag
return 0 // probably canceled
endif
endif
doupdate
AddMovieFrame
killwindow season
killwaves $nextimage
if( V_Flag!=0 )
Print "Add movie frame failed, err= ",V_Flag,", frame ",i
if( isMac && wAudio )
Print "Specifing sound may not work on Mac"
endif
break
endif
i += 1
while(i<nframes)
if( wAudio )
yuanAudio= scar[100000+p]
AddMovieAudio/Z yuanAudio
if( V_Flag!=0 )
Print "Add movie audio failed, err= ",V_Flag
endif
endif
CloseMovie/Z
if( V_Flag!=0 )
Print "Close movie failed, err= ",V_Flag
endif
Sleep/S 1 // without this, Mac sometimes gives a file not a movie error; DoUpdate did not help
PlayMovie/P=moviesPath as fName+fExtension
end
When I run this procedure it always turns out :
Add movie frame failed, err= 1 , frame 1
I don't know where the error is.
And when I delete these lines in the procedure
if( V_Flag!=0 )
Print "Add movie frame failed, err= ",V_Flag,", frame ",i
if( isMac && wAudio )
Print "Specifing sound may not work on Mac"
endif
break endif
the procedure can run as I expect but the image quality in the movie becomes worse with the loop number increasing.
Can someone help me? My Igor version is Igor Pro 8. The operating system version is win10 64 bit. I think the best value for nframes and fRate in the procedure are 20 and 1, respectively.
Thanks a lot!
Deleted my comment ...nevermind, I didn't see the attachments... I hope someone else can help.
August 13, 2019 at 04:31 am - Permalink
In reply to You have to provide more… by chozo
Thank you.
August 13, 2019 at 07:01 am - Permalink
I really don't have sufficient information here but if your AppendMovieFrame command includes the /Z flag then you should pay attention to the value of V_Flag and if it is non-zero you need to determine the reason for the error.
If the movie quality deteriorates with increasing frames you should look at the way you are initializing the NewMovie. If your codec allows you to set the key frame, you will have to reduce the number that you are using because apparently the compression is not keeping up with the relative changes between frames. In fact, it might be a good idea to select a codec that is more appropriate for the type of variations that you have between frames.
A.G.
August 13, 2019 at 12:31 pm - Permalink
In reply to I really don't have… by Igor
Thank you. I've modified my question. Could you help me further? When I run this procedure, I cannot open a new movie if I omit the /z flag in the Newmovie command.
August 13, 2019 at 06:27 pm - Permalink
In reply to I really don't have… by Igor
I add /cf=1 to the Newmovie command so the picture quality problem has been solved. When I add /z flag to Addmovieframe, Newmovie, etc, the procedure can run although it will get slow down as time passes by, but that may be enough for me. Thank you.
August 13, 2019 at 07:19 pm - Permalink
When you add /CF=1 there is no compression and each one of your images could potentially add a lot of memory which will slow your computer down. Try something like a factor of 10 and see if that improves your performance. I'm not going to comment on the rest of the code because I am not a fan of killing the window each time. Why not simply overwrite the image data, call doUpdate to make sure that it is displayed and then AddMovieFrame.
August 13, 2019 at 07:43 pm - Permalink
In reply to When you add /CF=1 there is… by Igor
Thank you! I've accepted your advice to overwrite the image data instead of killing the window each time.
August 13, 2019 at 08:08 pm - Permalink