rling
19th June 2010, 03:58
Hi Avisynth users
I have a set of functions I have used many times for non-linear editing, especially continuity editing, of home video, weddings, travel videos etc. I'll post them here in case they are useful to anyone else.
Some advantages of scripts that use these functions:
- easy to read and edit -- it looks like an EDL (Edit Decisions List)
- shorter than the equivalent script that uses Trim() and Splice()
- it's easy to add comments, so you can understand it later on...
Support for basic continuity editing is built in -- eg. "cutaways" or "reaction shots"
First, here is a part of a real edited video that uses these functions, so you can see what it looks like:
tape = AVISource("I:\tape1.AVI")
# black lead-in for fade-up
push(BlankClip(tape))
cut(0)
wait(30)
pop()
push(tape)
dis(36576,15) # Scene 284, golden buddha sitting outside temple
wait(36696) # max range: 36576 - 36716
dis(37844,15) # Scene 292, slow zoom on temple roof
wait(37935) # max range: 37844 - 37935
dis(37053,15) # Scene 287, carved door
wait(37192) # max range: 37053 - 37192
dis(37583,15) # Scene 290, row of stupas
wait(37711) # max range: 37583 - 37711
disa(38052,15)
disv(38188,15) # Scene 295, silhouetted bells
waitv(38188+75) # max range: 38188 - 38377
# slow-mo this scene as it is too short
push(changespeed(tape, 0.5))
disv(38377*2-75,15) # Scene 295, silhouetted bells
waitv(38377*2) # max range: 38188 - 38377
disv(38052*2,15) # Scene 294, slow pan of scene to horizon
disa(38052,15) # Scene 294, slow pan of scene to horizon
waitv(38122*2) # max range: 38032 - 38187
pop()
# cut to inside
cut(36717) # Scene 285, incense bowls & monks kneeling, from side
wait(36832) # max range: 36717 - 36832
cut(38955) # Scene 300, monks kneeling, from the rear
wait(39078) # max range: 38955 - 39078
#dis(36833,15) # Scene 286, crash zoom on silhouetted banners
#wait(37052) # max range: 36833 - 37052
cut(37487) # Scene 289, still of temple freize
wait(37582) # max range: 37487 - 37582
dis(37193,15) # Scene 288, still of temple freize
wait(37486) # max range: 37193 - 37486
cut(377120) # Scene 291, gold ornaments
wait(37843) # max range: 37712 - 37843
# slow-mo this scene as it is too short
disa(37936,15) # Scene 293, slow zoom on gold ornaments
push(changespeed(tape, 0.25))
disv(37936*4,15) # Scene 293, slow zoom on gold ornaments
waitv(37936*4+75) # max range: 37936 - 38031
pop()
#cut(38378) # Scene 296, gold ornaments, out of focus leave out
#wait(38589) # max range: 38378 - 38589
#cut(38590) # Scene 297, gold ornaments, out of focus leave out
#wait(38747) # max range: 38590 - 38747
# outside
cut(38748) # Scene 298, exterior mosaic
wait(38845) # max range: 38748 - 38845
dis(38846,15) # Scene 299, exterior mosaic
wait(38954) # max range: 38846 - 38954
cut(39079) # Scene 301, monks in courtyard
wait(39192) # max range: 39079 - 39192
[... more of the same ...]
pop()
# fade to black
push(BlankClip(tape))
disv(0, 15)
wait(20)
pop()
return finish()
SIMPLE EXAMPLE:
Now to explain some of the functions, here is a simple example... it would be easy to do this using Trim() and Splice(), so you might wonder why I need these functions at all, but trust me it gets more complicated later!
Import("continuity.avs")
global debug_sync = true
avi = AudioDub(BlankClip(length=1000,width=100,height=100),Tone(type="Silence"))
push(avi)
cut(100)
wait(150)
cut(200)
wait(250)
dis(300,10)
wait(350)
pop()
return finish()
Lets look line by line:
Import("continuity.avs")
This function imports my continuity editing functions.
global debug_sync = true
Turning this boolean on causes frame numbers to be displayed on input AVIs, and also displays the audio under the video in the output AVI, so that we can see what frames are being used in both video and audio. Normally, you would leave debug_sync turned off.
avi = AudioDub(BlankClip(length=1000,width=100,height=100),Tone(type="Silence"))
push(avi)
These lines create a dummy blank AVI and set it as the input AVI, that we are currently taking video and audio from. For me the input is usually a complete DV tape with many scenes. (Actually you can probably guess that push() pushes the AVI onto a stack, but I will explain that later.)
cut(100)
wait(150)
This says, cut to frame 100 of the input clip, then wait until we reach frame 150 of the input clip. That is, the frames 100-150 inclusive (51 frames) are the first piece of output. We can't wait() for a frame that is earlier than the one we cut() to. For example, wait(90) after cut(100) would be an error. But we could have used wait(100), that would output just one frame (frame 100).
cut(200)
wait(250)
This says, cut to frame 200 of the input clip, then wait until we reach frame 250 of the input clip. That is, the frames 200-250 inclusive (51 frames) are appended to the first piece of output, the total output is now 102 frames.
dis(300,10)
wait(350)
This says, dissolve to frame 300 of the input clip, with an overlap of 10. Then wait until we reach frame 350 of the input clip. Now we have output another 51 frames, but the first 10 of those frames are dissolved with the last 10 frames of the previous output. So the output is only 41 frames longer than before. The total output is 143 frames.
pop()
This function pops off the input clip we pushed at line 2, because we are now finished with it. We don't actually need to do this in this case, but it is tidy!
return finish()
This function indicates that this is the end of the editing. finish() returns the edited output.
BASIC CONTINUITY EDITING:
Next lets look at unsynchronised video and audio (eg. for "cutaway shots" or "reaction shots"). This is a basic trick of continuity editing, I use it all the time. Say we replace all the lines between the push() and pop() with these lines:
cut(100)
wait(150)
cutv(500)
waitv(520)
cutv(600)
waitv(620)
cutv2a()
wait(200)
Line by line again:
cut(100)
wait(150)
The output starts at frame 100, and continues up to and including frame 150. So we have 51 output frames so far.
cutv(500)
This function cuts the video to frame 500, but the audio stays where it was, at frame 150. So, this begins a "cutaway shot", where we take video from another part of the tape without changing the soundtrack. The video and audio are now unsynchronised.
waitv(520)
This function waits until video frame 520. (We can't use wait() here, because the video and audio are unsynchronised, so video frame X and audio frame X will happen at different times. Using wait() would trigger an assert.) Anyway, this waitv() outputs a video-only clip of frames 500-520. Remember that the audio is still only up to frame 150. We haven't said anything about the audio yet, so no audio is output.
cutv(600)
waitv(620)
These two functions output another video-only clip of frames 600-620. Just to show that we can join together cutaway shots. We still haven't said anything about the audio so it stays at frame 150.
cutv2a()
This function ("cut video to audio") resynchronises the video to the current audio position. When we desynchronised the video, the audio was at frame 150, and we added 42 video frames since then. So, this function outputs the next 42 frames of audio from the current audio position (frames 151-192 inclusive) making the streams the same length again. The next audio frame will be frame 193, so it cuts the video to frame 193 as well. Now the video and audio are synchronised again.
wait(200)
This line waits until frame 200. So, frames 193-200 (of both video and audio) are appended to the output. The final output is a clip of 101 frames, where the audio is taken from frames 100-200 inclusive and the video is made up of 4 small clips.
Often, cutaways are used in recorded TV interviews to make an answer shorter. You can't just cut out a section of video and audio from an answer, because the person will move slightly so you get a "jump cut" in the video. So, first you cut to a brief shot of the interviewer. Then you cut out the audio you don't want, perhaps joining using a dissolve so you don't get a "pop" in the soundtrack. Then you can cut back from the interviewer to the person's answer. And you avoid a jump cut. Here is the script fragment for this, showing how we take an answer that lasts for frames 100-300, and cut out the audio from frames 150-200 without a jump cut:
cut(100) # cut to the person starting their answer
wait(140) # wait till shortly before the start of the audio we want to cut out
cutv(5000) # cut video to a shot of the interviewer (which was actually taken much later)
waita(149) # wait up to and including the last frame before the audio we want to cut out
cuta(201) # cut to the first frame after the audio to be cut out, the video is not affected
waitv(5050) # wait till the interviewer has been seen for about 50 frames (51 to be exact)
cutv2a() # cut video back to the person giving the answer (frame 241).
wait(300) # wait till the end of the answer
The length of this sequence is determined by the length of the 2 audio segments, the first from 100-149 (50 frames) and the next from 201-300 (100 frames) so the total is 150 frames. We can change the parameters to cutv() and waitv() without changing the length of the sequence. But if we make the distance between cutv() and waitv() too long (like say 500 frames), we get an error at wait(300), because after cutv2a() the synchronised position will be already past frame 300 and we can't wait for a frame that has already passed!
What if we wanted to use dissolves instead of cuts? Here are the functions for that. We still have to start with a cut, because there is no previous video to dissolve with.
cut(100) # cut to the person starting their answer
wait(140) # wait till shortly before the start of the audio we want to cut out
disv(5000,5) # dissolve video to a shot of the interviewer, with an overlap of 5
waita(149) # wait up to and including the last frame before the audio we want to cut out
disa(201,5) # dissolve to the first frame after the audio to be cut out, with an overlap of 5
waitv(5050) # wait till the interviewer has been seen for about 50 frames
disv2a(5) # dissolve video back to the person giving the answer
wait(300) # wait till the end of the answer
The length of this sequence is 5 less than the previous one, because there is a 5 frame overlap between the 2 audio segments, so the total is 145 frames.
You can see that cutv2a() and disv2a() save you having to work out the maths. So are there functions called cuta2v() and disa2v()?? Yes!! cuta2v() is the opposite of cutv2a(). It cuts the audio to match the current video position. And disa2v() is the opposite of disa2v(). Suppose we changed the second last line of the above script to:
disa2v(5)
This script fragment is the same as before, except instead of cutting the video to synchronise with the audio, it cuts the audio to synchronise with the video, which is frame 5051. Now the video and audio are synchronised again. But, the call to wait(300) is an error, because frame 5051 is already past frame 300. If we used wait(6000) instead, it would work (if the input was long enough).
Usually, cuta2v() and disa2v() are more useful for doing the opposite of a "cutaway shot" - where we want to replace the audio with audio from another time:
cut(100)
wait(150)
cuta(500) # cut audio to frame 500, video stays at frame 150
waita(520) # output 21 audio frames from 500-520 inclusive
cuta2v() # output 21 video frames (151-171) and cut audio to sync with video at frame 172
wait(200) # output synchronised frames 172-200 inclusive
Thats it for now. See the functions in the next post.
I can post more explanation if anyone is interested
Cheers
R
I have a set of functions I have used many times for non-linear editing, especially continuity editing, of home video, weddings, travel videos etc. I'll post them here in case they are useful to anyone else.
Some advantages of scripts that use these functions:
- easy to read and edit -- it looks like an EDL (Edit Decisions List)
- shorter than the equivalent script that uses Trim() and Splice()
- it's easy to add comments, so you can understand it later on...
Support for basic continuity editing is built in -- eg. "cutaways" or "reaction shots"
First, here is a part of a real edited video that uses these functions, so you can see what it looks like:
tape = AVISource("I:\tape1.AVI")
# black lead-in for fade-up
push(BlankClip(tape))
cut(0)
wait(30)
pop()
push(tape)
dis(36576,15) # Scene 284, golden buddha sitting outside temple
wait(36696) # max range: 36576 - 36716
dis(37844,15) # Scene 292, slow zoom on temple roof
wait(37935) # max range: 37844 - 37935
dis(37053,15) # Scene 287, carved door
wait(37192) # max range: 37053 - 37192
dis(37583,15) # Scene 290, row of stupas
wait(37711) # max range: 37583 - 37711
disa(38052,15)
disv(38188,15) # Scene 295, silhouetted bells
waitv(38188+75) # max range: 38188 - 38377
# slow-mo this scene as it is too short
push(changespeed(tape, 0.5))
disv(38377*2-75,15) # Scene 295, silhouetted bells
waitv(38377*2) # max range: 38188 - 38377
disv(38052*2,15) # Scene 294, slow pan of scene to horizon
disa(38052,15) # Scene 294, slow pan of scene to horizon
waitv(38122*2) # max range: 38032 - 38187
pop()
# cut to inside
cut(36717) # Scene 285, incense bowls & monks kneeling, from side
wait(36832) # max range: 36717 - 36832
cut(38955) # Scene 300, monks kneeling, from the rear
wait(39078) # max range: 38955 - 39078
#dis(36833,15) # Scene 286, crash zoom on silhouetted banners
#wait(37052) # max range: 36833 - 37052
cut(37487) # Scene 289, still of temple freize
wait(37582) # max range: 37487 - 37582
dis(37193,15) # Scene 288, still of temple freize
wait(37486) # max range: 37193 - 37486
cut(377120) # Scene 291, gold ornaments
wait(37843) # max range: 37712 - 37843
# slow-mo this scene as it is too short
disa(37936,15) # Scene 293, slow zoom on gold ornaments
push(changespeed(tape, 0.25))
disv(37936*4,15) # Scene 293, slow zoom on gold ornaments
waitv(37936*4+75) # max range: 37936 - 38031
pop()
#cut(38378) # Scene 296, gold ornaments, out of focus leave out
#wait(38589) # max range: 38378 - 38589
#cut(38590) # Scene 297, gold ornaments, out of focus leave out
#wait(38747) # max range: 38590 - 38747
# outside
cut(38748) # Scene 298, exterior mosaic
wait(38845) # max range: 38748 - 38845
dis(38846,15) # Scene 299, exterior mosaic
wait(38954) # max range: 38846 - 38954
cut(39079) # Scene 301, monks in courtyard
wait(39192) # max range: 39079 - 39192
[... more of the same ...]
pop()
# fade to black
push(BlankClip(tape))
disv(0, 15)
wait(20)
pop()
return finish()
SIMPLE EXAMPLE:
Now to explain some of the functions, here is a simple example... it would be easy to do this using Trim() and Splice(), so you might wonder why I need these functions at all, but trust me it gets more complicated later!
Import("continuity.avs")
global debug_sync = true
avi = AudioDub(BlankClip(length=1000,width=100,height=100),Tone(type="Silence"))
push(avi)
cut(100)
wait(150)
cut(200)
wait(250)
dis(300,10)
wait(350)
pop()
return finish()
Lets look line by line:
Import("continuity.avs")
This function imports my continuity editing functions.
global debug_sync = true
Turning this boolean on causes frame numbers to be displayed on input AVIs, and also displays the audio under the video in the output AVI, so that we can see what frames are being used in both video and audio. Normally, you would leave debug_sync turned off.
avi = AudioDub(BlankClip(length=1000,width=100,height=100),Tone(type="Silence"))
push(avi)
These lines create a dummy blank AVI and set it as the input AVI, that we are currently taking video and audio from. For me the input is usually a complete DV tape with many scenes. (Actually you can probably guess that push() pushes the AVI onto a stack, but I will explain that later.)
cut(100)
wait(150)
This says, cut to frame 100 of the input clip, then wait until we reach frame 150 of the input clip. That is, the frames 100-150 inclusive (51 frames) are the first piece of output. We can't wait() for a frame that is earlier than the one we cut() to. For example, wait(90) after cut(100) would be an error. But we could have used wait(100), that would output just one frame (frame 100).
cut(200)
wait(250)
This says, cut to frame 200 of the input clip, then wait until we reach frame 250 of the input clip. That is, the frames 200-250 inclusive (51 frames) are appended to the first piece of output, the total output is now 102 frames.
dis(300,10)
wait(350)
This says, dissolve to frame 300 of the input clip, with an overlap of 10. Then wait until we reach frame 350 of the input clip. Now we have output another 51 frames, but the first 10 of those frames are dissolved with the last 10 frames of the previous output. So the output is only 41 frames longer than before. The total output is 143 frames.
pop()
This function pops off the input clip we pushed at line 2, because we are now finished with it. We don't actually need to do this in this case, but it is tidy!
return finish()
This function indicates that this is the end of the editing. finish() returns the edited output.
BASIC CONTINUITY EDITING:
Next lets look at unsynchronised video and audio (eg. for "cutaway shots" or "reaction shots"). This is a basic trick of continuity editing, I use it all the time. Say we replace all the lines between the push() and pop() with these lines:
cut(100)
wait(150)
cutv(500)
waitv(520)
cutv(600)
waitv(620)
cutv2a()
wait(200)
Line by line again:
cut(100)
wait(150)
The output starts at frame 100, and continues up to and including frame 150. So we have 51 output frames so far.
cutv(500)
This function cuts the video to frame 500, but the audio stays where it was, at frame 150. So, this begins a "cutaway shot", where we take video from another part of the tape without changing the soundtrack. The video and audio are now unsynchronised.
waitv(520)
This function waits until video frame 520. (We can't use wait() here, because the video and audio are unsynchronised, so video frame X and audio frame X will happen at different times. Using wait() would trigger an assert.) Anyway, this waitv() outputs a video-only clip of frames 500-520. Remember that the audio is still only up to frame 150. We haven't said anything about the audio yet, so no audio is output.
cutv(600)
waitv(620)
These two functions output another video-only clip of frames 600-620. Just to show that we can join together cutaway shots. We still haven't said anything about the audio so it stays at frame 150.
cutv2a()
This function ("cut video to audio") resynchronises the video to the current audio position. When we desynchronised the video, the audio was at frame 150, and we added 42 video frames since then. So, this function outputs the next 42 frames of audio from the current audio position (frames 151-192 inclusive) making the streams the same length again. The next audio frame will be frame 193, so it cuts the video to frame 193 as well. Now the video and audio are synchronised again.
wait(200)
This line waits until frame 200. So, frames 193-200 (of both video and audio) are appended to the output. The final output is a clip of 101 frames, where the audio is taken from frames 100-200 inclusive and the video is made up of 4 small clips.
Often, cutaways are used in recorded TV interviews to make an answer shorter. You can't just cut out a section of video and audio from an answer, because the person will move slightly so you get a "jump cut" in the video. So, first you cut to a brief shot of the interviewer. Then you cut out the audio you don't want, perhaps joining using a dissolve so you don't get a "pop" in the soundtrack. Then you can cut back from the interviewer to the person's answer. And you avoid a jump cut. Here is the script fragment for this, showing how we take an answer that lasts for frames 100-300, and cut out the audio from frames 150-200 without a jump cut:
cut(100) # cut to the person starting their answer
wait(140) # wait till shortly before the start of the audio we want to cut out
cutv(5000) # cut video to a shot of the interviewer (which was actually taken much later)
waita(149) # wait up to and including the last frame before the audio we want to cut out
cuta(201) # cut to the first frame after the audio to be cut out, the video is not affected
waitv(5050) # wait till the interviewer has been seen for about 50 frames (51 to be exact)
cutv2a() # cut video back to the person giving the answer (frame 241).
wait(300) # wait till the end of the answer
The length of this sequence is determined by the length of the 2 audio segments, the first from 100-149 (50 frames) and the next from 201-300 (100 frames) so the total is 150 frames. We can change the parameters to cutv() and waitv() without changing the length of the sequence. But if we make the distance between cutv() and waitv() too long (like say 500 frames), we get an error at wait(300), because after cutv2a() the synchronised position will be already past frame 300 and we can't wait for a frame that has already passed!
What if we wanted to use dissolves instead of cuts? Here are the functions for that. We still have to start with a cut, because there is no previous video to dissolve with.
cut(100) # cut to the person starting their answer
wait(140) # wait till shortly before the start of the audio we want to cut out
disv(5000,5) # dissolve video to a shot of the interviewer, with an overlap of 5
waita(149) # wait up to and including the last frame before the audio we want to cut out
disa(201,5) # dissolve to the first frame after the audio to be cut out, with an overlap of 5
waitv(5050) # wait till the interviewer has been seen for about 50 frames
disv2a(5) # dissolve video back to the person giving the answer
wait(300) # wait till the end of the answer
The length of this sequence is 5 less than the previous one, because there is a 5 frame overlap between the 2 audio segments, so the total is 145 frames.
You can see that cutv2a() and disv2a() save you having to work out the maths. So are there functions called cuta2v() and disa2v()?? Yes!! cuta2v() is the opposite of cutv2a(). It cuts the audio to match the current video position. And disa2v() is the opposite of disa2v(). Suppose we changed the second last line of the above script to:
disa2v(5)
This script fragment is the same as before, except instead of cutting the video to synchronise with the audio, it cuts the audio to synchronise with the video, which is frame 5051. Now the video and audio are synchronised again. But, the call to wait(300) is an error, because frame 5051 is already past frame 300. If we used wait(6000) instead, it would work (if the input was long enough).
Usually, cuta2v() and disa2v() are more useful for doing the opposite of a "cutaway shot" - where we want to replace the audio with audio from another time:
cut(100)
wait(150)
cuta(500) # cut audio to frame 500, video stays at frame 150
waita(520) # output 21 audio frames from 500-520 inclusive
cuta2v() # output 21 video frames (151-171) and cut audio to sync with video at frame 172
wait(200) # output synchronised frames 172-200 inclusive
Thats it for now. See the functions in the next post.
I can post more explanation if anyone is interested
Cheers
R