Ren'Py [solved] Seamlessly alternate between two videos using an imagebutton

Tribe

Member
Game Developer
May 5, 2021
221
480
As the title states, I'm trying learn if it is possible to show a video and alternate between that video and another using an imagebutton. The button would stop the video and play the alternate video from the same time.

Another thing is that the videos will have identical audio tracks. To avoid audio interruption I thought syncing the videos to a single audio track would be ideal. Is it possible to sync a video file with an audio file that is already playing?

So, yeah. Is this doable? Thanks everyone.
 

anne O'nymous

I'm not grumpy, I'm just coded that way.
Modder
Respected User
Donor
Jun 10, 2017
10,266
15,082
Another thing is that the videos will have identical audio tracks. To avoid audio interruption I thought syncing the videos to a single audio track would be ideal. Is it possible to sync a video file with an audio file that is already playing?
Not perfectly, and not without effort.

But... Why don't just have two videos and one independent audio track ? That way, whatever how many time the player change the video, the audio track would never change, and so stay perfectly synced.
 
  • Like
Reactions: Tribe

Tribe

Member
Game Developer
May 5, 2021
221
480
Not perfectly, and not without effort.

But... Why don't just have two videos and one independent audio track ? That way, whatever how many time the player change the video, the audio track would never change, and so stay perfectly synced.
I think you said what I said in a different (smarter) way. I thought playing the two videos over an independent audio track would work best. The only thing I'm missing is playing a video and syncing it with an audio track that's already running. If its possible, what I need to know is how to sync a video file with an audio track that is already playing.
 
Last edited:

Turning Tricks

Rendering Fantasies
Game Developer
Apr 9, 2022
873
1,875
I think you said what I said in a different (smarter) way. I thought playing the two videos over an independent audio track would work best. The only thing I'm missing is playing a video and syncing it with an audio track that's already running. If its possible, what I need to know is how to sync a video file with an audio track that is already playing.

I've experimented with ATL transitions for Ren'py animation loops and the best way I found of switching seamlessly between two displayables was to have both of them running at the same time on their own layers and then just use show and hide with a fade in and fade out effect.

The scene I was doing was for a rotating skull that would be magically transformed from natural bone to a transparent crystal. Practically every way I tried to do the transistion had some sort of lag/pause or hiccup or forced the new animation to start from the beginning. But when I just ran booth loops at the same time and then hid the top layer with a very slow Dissolve(2.0), it worked perfectly.

It should be easy to do the same with two movies and then use an image button toggle() to switch between them.

As for the audio, I don't know if you followed the discussion we were having in the Dev forum about syncing sex sounds with a movie - but the easiest way by far is just to add the sound track to the movie itself (by whatever video editor you use). But I get what you are trying to do... have two movies running (I am thinking they are two angles of the same scene maybe?) and you want the audio to be in sync, no matter which movie is being shown. I think my example above is the best way to do that. Have both movies playing at the same time and just hide/show the layers they are on. They should stay in sync with each other (and therefore with the audio file you have running.

If that doesn't work for you, it might be possible to use Ren'py's system to queue up the audio files so when you switch movies with the imagebutton the proper audio file starts right away. But that means the files will start over when you switch.

AFAIK, Ren'py has no way to create 'key frames" in movies to sync up audio or other actions.

There's also a function in Ren'py that may help you. Honestly though, I have no experience with this particular function yet. From just scanning the docs and some examples, it seems it syncs up separate audio tracks so when you switch between them, they are always in sync with each other. That would be handy if you have different tracks you wanted to use for different movies, but I am not sure it helps you in this example.

If you want to look it over yourself, check webpage out. This person has one of the best examples of how to use this function I have seen so far.
 
  • Like
  • Star-struck
Reactions: DuniX and Tribe

Tribe

Member
Game Developer
May 5, 2021
221
480
I've experimented with ATL transitions for Ren'py animation loops and the best way I found of switching seamlessly between two displayables was to have both of them running at the same time on their own layers and then just use show and hide with a fade in and fade out effect.

The scene I was doing was for a rotating skull that would be magically transformed from natural bone to a transparent crystal. Practically every way I tried to do the transistion had some sort of lag/pause or hiccup or forced the new animation to start from the beginning. But when I just ran booth loops at the same time and then hid the top layer with a very slow Dissolve(2.0), it worked perfectly.

It should be easy to do the same with two movies and then use an image button toggle() to switch between them.

As for the audio, I don't know if you followed the discussion we were having in the Dev forum about syncing sex sounds with a movie - but the easiest way by far is just to add the sound track to the movie itself (by whatever video editor you use). But I get what you are trying to do... have two movies running (I am thinking they are two angles of the same scene maybe?) and you want the audio to be in sync, no matter which movie is being shown. I think my example above is the best way to do that. Have both movies playing at the same time and just hide/show the layers they are on. They should stay in sync with each other (and therefore with the audio file you have running.

If that doesn't work for you, it might be possible to use Ren'py's system to queue up the audio files so when you switch movies with the imagebutton the proper audio file starts right away. But that means the files will start over when you switch.

AFAIK, Ren'py has no way to create 'key frames" in movies to sync up audio or other actions.

There's also a function in Ren'py that may help you. Honestly though, I have no experience with this particular function yet. From just scanning the docs and some examples, it seems it syncs up separate audio tracks so when you switch between them, they are always in sync with each other. That would be handy if you have different tracks you wanted to use for different movies, but I am not sure it helps you in this example.

If you want to look it over yourself, check webpage out. This person has one of the best examples of how to use this function I have seen so far.
Yes!
Based on your example, the hide/show layer example should work perfectly! I didn't even know you could hide a layer to be honest... I just have to brush up on defining and hiding layers :LOL: it shouldn't be too hard, right? I will begin reading up on this right away! And thanks for the additional information on audio syncing! This is great information that I will probably put to use in the near future!
 
  • Like
Reactions: DuniX

Turning Tricks

Rendering Fantasies
Game Developer
Apr 9, 2022
873
1,875
Yes!
Based on your example, the hide/show layer example should work perfectly! I didn't even know you could hide a layer to be honest... I just have to brush up on defining and hiding layers :LOL: it shouldn't be too hard, right? I will begin reading up on this right away! And thanks for the additional information on audio syncing! This is great information that I will probably put to use in the near future!
Well, when you use show to display an image (or any other displayable that is defined as an image) it just plays that on top of the previous displayable you had. That's why most of us who tend to use full screen renders use scene instead, since scene clears any other layers currently being displayed. Show was more handy for sprite management.

So, if you go show image1 , then image1 will be displayed. If you then go show image2, image2 gets displayed on top of image1, but image1 is still there.

In my example above, I just had to start both animations at the same time by using

Python:
    show skull_2
    show skull_1
    pause 1.5
    mco angry "Transi limen o dignus famulus..."
    mco angry "Nunc veni!"
    hide skull_1 with Dissolve(2.0)
    mco happy "Yes!"
And this is how that looked when the player saw it...

View attachment skull_example.mp4

















Now, this simple technique probably won't help you if you are switching back and forth between two active movies. I'm thinking you will have to make screens with those movies and then use an imagebutton toggle() to cycle between them. I don't have an example handy right now as I'm in a crunch on my next release. but it shouldn't be hard to read up on .

EDIT: I forgot to mention the reason why my example above probably won't do you much good, is because when you hide a displayable it removes it from that layer. I believe if you then use show again, the animation will start from the beginning again. Whereas a screen can be toggled and it's still active, even if not currently shown.
 
  • Wow
  • Yay, new update!
Reactions: DuniX and Tribe

Tribe

Member
Game Developer
May 5, 2021
221
480
Well, when you use show to display an image (or any other displayable that is defined as an image) it just plays that on top of the previous displayable you had. That's why most of us who tend to use full screen renders use scene instead, since scene clears any other layers currently being displayed. Show was more handy for sprite management.

So, if you go show image1 , then image1 will be displayed. If you then go show image2, image2 gets displayed on top of image1, but image1 is still there.

In my example above, I just had to start both animations at the same time by using

Python:
    show skull_2
    show skull_1
    pause 1.5
    mco angry "Transi limen o dignus famulus..."
    mco angry "Nunc veni!"
    hide skull_1 with Dissolve(2.0)
    mco happy "Yes!"
Ahah! Screen toggle!
I was having the exact issues you spoke of here. I'll show them in screens now. I can't see why that wouldn't work. Lets see!
Thanks again!
 
  • Like
Reactions: Turning Tricks

Tribe

Member
Game Developer
May 5, 2021
221
480
Hmmm. ToggleScreen() stops and restarts the video...
Trying something in a loop using alpha channels... Kinda losing hope here
 

Tribe

Member
Game Developer
May 5, 2021
221
480
SUCCESS!
Turning Tricks anne O'nymous
You guys kick ass!
I showed the video on 2 screens (probably can do in 1 screen) then called what will be an imagebutton in a loop which alters the alpha of the top video. All I need to do now is play the audio file along with it. Piece of cake!!!

Good luck with your release Turning Tricks, I'm sending you all the good vibes so bugs will go away. Thanks for always helping us, Anne!


Python:
init:
    default playing = True
    default alpha_var = 0.0
    
init python:
    setattr(store, "movie22", Movie(size=(1920,1080), play="images/assets/test videos/boobs (22).webm", channel="animation22"))
    setattr(store, "movie25", Movie(size=(1920,1080), play="images/assets/test videos/boobs (25).webm", channel="animation25"))

label start:
    scene bg room

    "hello"

    $ alpha_var = 0.0
    $ playing = True
    
    show screen alt_video_screen_1
    show screen alt_video_screen_2

    python:
        while playing:
            UIreturn = renpy.call_screen("button_screen")

    return

screen alt_video_screen_1:

    add getattr(store, "movie25")

screen alt_video_screen_2:

    add getattr(store, "movie22"):
        alpha alpha_var

screen button_screen:
    textbutton "Hi":
        action [SetVariable("alpha_var", Alternate_Alphas())]

init python:
    def Alternate_Alphas():
        global alpha_var

        if alpha_var != 0.8:
            return 0.8
        return 0.0
 

osanaiko

Engaged Member
Modder
Jul 4, 2017
2,187
3,644
BTW you don't need to use python and setattr/getattr for those movie displayables.

A simple renpy assignment will work the same

Code:
default movie22 = Movie(size=(1920,1080), play="images/assets/test videos/boobs (22).webm", channel="animation22"))
 
  • Like
Reactions: Tribe

79flavors

Well-Known Member
Respected User
Jun 14, 2018
1,561
2,183
SUCCESS!

[...] All I need to do now is play the audio file along with it.
If you're just altering the alpha of the "upper" video, just include the audio in one of the video files. Then there's no chance the audio will go out of sync. Since both video files will always be shown on screen (even if the player can't see one of them) the audio should still be playing, regardless of the alpha values.
 

Tribe

Member
Game Developer
May 5, 2021
221
480
BTW you don't need to use python and setattr/getattr for those movie displayables.

A simple renpy assignment will work the same

Code:
default movie22 = Movie(size=(1920,1080), play="images/assets/test videos/boobs (22).webm", channel="animation22"))
Thanks! Its been so long since I defined displayables one at a time that I can barely remember how to do it :LOL:
In my games I just loop through all the videos in the game and store them as the path name and be done with it since they are generally files added by my players.

If you're just altering the alpha of the "upper" video, just include the audio in one of the video files. Then there's no chance the audio will go out of sync. Since both video files will always be shown on screen (even if the player can't see one of them) the audio should still be playing, regardless of the alpha values.
Thank you, 79flavors! This is exactly what I'm going to do. :love: