Jump to content
galagast

Question: hou.playbar.play()

Recommended Posts

I have this pseudo simple script:

import hou

# store paramter to parm variable
parm = hou.parm('/obj/box/CONTROLS/count')
# store the current value
val = parm.eval()
# increment the value
parm.set(val+1)

# go to frame 1
hou.setFrame(1)
# play
hou.playbar.play()

box is a Geometry container.
CONTROLS is a Null SOP.
count is an integer spare parameter.

I use this script as a shelf tool, where I also assigned a shortcut.

  • Whenever I run the script via the shortcut key assigned, the count parameter gets incremented (+1), then the playbar starts to play... (so far so good)
  • Immediately after, I run the script AGAIN using the same shortcut, the count parameter does gets incremented, but the playbar stops playing.
  • I repeat the process, then the playbar would always switch from playing and not playing.

Q: How do I keep the playbar playing?

I tried adding a check:

if not hou.playbar.isPlaying():
	hou.playbar.play()

Added this too:

hou.setFrame(1)
hou.playbar.stop() # added this
hou.playbar.play()

I also tried:

hou.hscript("fcur 1")
hou.hscript("play")

Hscript:

set val = `ch("obj/box/CONTROLS/count")`
opparm obj/box/CONTROLS count (`$val+1`)
fcur 1
play

None seems to keep the playbar playing. :(

Edited by galagast

Share this post


Link to post
Share on other sites

You may not have counted on the fact that multiple events are sent on the same frame. This may mess up simple flip/flop logic approaches. If you install the callback even viewer, from the help, you can see the events that are flowing through the playbar.

I am not sure what your final timeline control goal is, but here is a short script where I made a tool button that basically acts as a start/stop/rewind but also updates the count field on the NULL. I added an additional integer value to the NULL as well. This is called last_frame which holds the last frame number when this count value was updated. So the first thing we do when we receive an event is to examine the frame number for the event. If it is the same as our last_frame value then the work needed done on this frame is assumed to be completed (thus we don't increment count).

import hou

p_count = hou.parm('/obj/box_object1/CONTROLS/count')
p_last_frame = hou.parm('/obj/box_object1/CONTROLS/last_frame')

# Setup event monitoring as described in help.
def outputPlaybarEvent(event_type, frame):
    print type(event_type)
    s = ""
    if s.find("FrameChanged") != -1:
        # Houdini gives us many events on the same frame.
        # We only want to count once for each frame number.
        if p_frame != frame:
            # Our last frame is not equal to this frame, issue a new count.
            val = p_count.eval()
            p_count.set(val+1)
    p_last_frame.set(frame)
    print "Playbar event", event_type, "at frame", frame
hou.playbar.addEventCallback(outputPlaybarEvent)


if hou.playbar.isPlaying():
    # We are already playing, so issue a stop.
    hou.playbar.stop()

else:
    # The user want to start playing, reset count to one.
    p_count.set(1) 
    hou.setFrame(1)
    p_last_frame.set(1)
    hou.playbar.play()

 

 

 

ap_toolshelf_playbar_control.hiplc

Untitled-1.jpg

Edited by Atom

Share this post


Link to post
Share on other sites

Hi Atom, thank you for looking into this.

Unfortunately, it does not seem to be working as intended.

Here's what I did to install it:

  1. Downloaded and opened your hip file.
  2. Created a new Shefl Tool.
  3. Pasted your code above.
  4. Added global shortcut key (alt+pagedown) -- any shortcut would do
  5. Closed the Edit Tool window.
  6. Went inside the box_object1 to look at the CONTROLS parameter.

Now I started to test the script.

  1. Pressed the shortcut alt+pagedown:
    1. The playbar started playing. (which is ok)
    2. Houdini console popped up. (also ok)
  2. Pressed the shortcut again:
    1. "Last Frame" parameter was updated. (ok)
    2. But the "count" parameter stayed at "1". (not ok)
    3. Also, the playbar animation stopped. (also not ok)
  3. I pressed the shortcut again:
    1. playbar went back to frame 1. (ok)
    2. playbar still not playing. (not ok)

Here's what I was hoping to happen:

  1. Press the shortcut alt+pagedown:
    1. Count increment +1.
    2. Go to frame 1.
    3. Playbar starts to animate.
  2. Press the shortcut again:
    1. Count increment +1.
    2. Go to frame 1.
    3. Playbar starts animating again.
  3. same as #2

 

I suppose I should describe what I intend to do with this.

I'm building a presentation for a talk about Houdini, and I wanted to do the presentation inside Houdini. Initially, I was contented with simply using a "Switch SOP" to change Presentation Slides using $F. But then, I wondered why not push it a bit more and incorporate animation? So the idea is, I need to have the playbar playing continuously. Then, when I press a shortcut button to go to the next slide, the Switch SOP's input should increment by 1 (or decrement by 1 if I want to go back a slide). I need the playbar animating because I could simply keyframe or put expressions on my nodes, then they would just animate from frame 1, or even do a looping animation while I'm on a certain slide.

Hopefully, I got the idea across. :)

Regards,
Jeff Lim

P.S. I noticed that on your code, at line 13, you have a p_frame variable which was not defined on the body. Is is supposed to be p_last_frame.eval()?

Edited by galagast

Share this post


Link to post
Share on other sites

Looking further into this, I noticed something else.

Using this code as a shelf tool:

import hou
hou.playbar.play()

If you click on it, the playbar would start playing (as expected).

But then if you press it again, two things could happen:
With Realtime Toggle ON -> The playbar would stop and return to frame 1.
With Realtime Toggle OFF -> The playbar would stop at the current frame.

Could this be a bug? (When realtime is ON)

Edited by galagast

Share this post


Link to post
Share on other sites

I tried your code and I find it does not actually return to frame 1. It actually returns to the frame it was on before you click the button. For instance manually move to frame #90 and try your tool. You'll see when you click it again with Realtime on, it returns frame #90, not 1.

It could be a bug, or a feature. When I am using an audio editing program I often want this feature, having the playhead snap back to where I just set it before I click play again. A quick way to review a certain piece of audio on a time line over and over.

If you are trying to build an alternate timeline control script you probably will need to examine the current state before you issue new commands. For instance if the timeline is playing, you may not want to issue a new play. This would avoid your above bug.

import hou

if hou.playbar.isPlaying() == False:
    hou.playbar.play()

It couldn't hurt to just report it as a bug and let SESI figure it out.

Edited by Atom

Share this post


Link to post
Share on other sites

Thank you Atom. Indeed, I tested it again, it does return to the initial frame you were at before clicking the tool. And you are correct, I can see its usefulness for playing back audio :)

Quote

If you are trying to build an alternate timeline control script you probably will need to examine the current state before you issue new commands. For instance if the timeline is playing, you may not want to issue a new play. This would avoid your above bug.

From my first post above, I did try to use that code to check if the playbar is already playing. But something about the sequence of codes is working odd for me:

Code Flow:

  1. For simplicity, we start fresh. Say I want a Python Tool that when pressed, should reset the playbar to frame 1.
    import hou
    hou.setFrame(1)

     

  2. I pressed PLAY manually.. then let it go a few frames forward.. then I clicked on the tool.
    -> Houdini did go back to frame 1.. but it stopped the animation.
  3. So I looked for the code to play the animation and added it to the tool:
    import hou
    hou.setFrame(1)
    hou.playbar.play()

     

  4. For consistency, I started to press PLAY again manually.. waited a for few frames.. then clicked on the tool.
    -> Houdini did go back to frame 1 as expected.. but the animation/playbar still stopped playing. It's as if it did not run line 3 to play the playbar.
  5. So, I tried to press the tool again.
    -> Now it played the animation!

 

Conclusion:
* That means, with that 3 line code (#3), I need to press the tool twice in order for it to properly work as I want. *

 

Concerns:

  • I'm curious why setFrame() would stop the animation while the playbar is playing. Or is there another way to go back to frame 1 whilst keeping the playbar playing?
  • And, (why) Python seems to disregard hou.playbar.play() after hou.setFrame(1).

 

Many thanks for looking into this Atom, hopefully I'm just missing something with how Python Scripting works in Houdini (Coming mostly from MaxScript).

Edited by galagast

Share this post


Link to post
Share on other sites
On 10/25/2016 at 8:15 AM, galagast said:

Concerns:

  • I'm curious why setFrame() would stop the animation while the playbar is playing. Or is there another way to go back to frame 1 whilst keeping the playbar playing?
  • And, (why) Python seems to disregard hou.playbar.play() after hou.setFrame(1).

 

Many thanks for looking into this Atom, hopefully I'm just missing something with how Python Scripting works in Houdini (Coming mostly from MaxScript).

Did you ever figure this out? I have run into the exact same problem. 

Share this post


Link to post
Share on other sites

Hi,

Unfortunately, due to time constraints, I was not able to further figure out why it was working like that.

- - - - - - - - - -

But for what I was trying to do (Houdini as a Powerpoint Presentation), I ended up downloading an APP on my phone called Custom Keypad.

Then I installed tightVNC on my desktop. The Keypad App connected through the Wifi to my desktop's VNC, where it sent keyboard commands that Houdini responded to. So on my phone, I simply mapped the 'play' and 'stop' keys, plus a python script to 'increment/decrement' the slide number to control my presentation.

Share this post


Link to post
Share on other sites

I had a similar issue where after changing frame it would stop playing.
From what I got out of it is that the set frame and play command are executed within a single frame and therefore do not work as intended.

In my case I fixed is by setting the set frame on the start of the code and the play at the end, so by the time the play was called enough time had passed.
 

The code below might offer some help. it used a event callback to see if the frame has changed to frame 1 before calling the play option. Afterwards it removes the callback.

def outputPlaybarEvent(event_type, frame):
    if event_type == hou.playbarEvent.FrameChanged and frame == 1:
        print event_type
        hou.playbar.play()
        hou.playbar.removeEventCallback(outputPlaybarEvent)

    return False
hou.playbar.addEventCallback(outputPlaybarEvent)         
hou.setFrame(1) 

 

Share this post


Link to post
Share on other sites

Awesome, I just tested this out. It works! Thanks Maurits!

A maxscript thread here appears to have a similar problem. One of the solutions offered also made use of callbacks. And it was also mentioned there that playing an animation is thread-blocking. I'm guessing that it is similar to how most animation packages handles playback.. thus the seemingly unexpected behavior. Atom was on the right track all along :D
 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×