Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Suggestion] show-text command could need position argument #4847

Closed
AxelTerizaki opened this issue Sep 8, 2017 · 14 comments
Closed

[Suggestion] show-text command could need position argument #4847

AxelTerizaki opened this issue Sep 8, 2017 · 14 comments

Comments

@AxelTerizaki
Copy link

AxelTerizaki commented Sep 8, 2017

mpv version and platform : latest stable / Windows

EDIT : Changed the title of the issue since this is not about positioning text via show-text anymore but is more about parameter expansion via the IPC protocol. As I understand it (and tried it) parameter expansion only works with LUA/JS scripting inside mpv or with input.conf file, but not through the IPC server mpv provides, which is used for instance by my app to display text above a video rendered via mpv. Parameter expansion should work via IPC as well.

I'm making an app using mpv to play out videos, and toyed around with the show-text command. While it's neat, positionning it on the screen could be interesting. For instance my app is for karaoke playback, so displaying messages via show-text actually overlaps with the lyrics displayed on top of the screen.

By default text is displayed in the top left corner of the screen.

I tried to change the vertical position by adding several \n in the text I send to mpv, but they didn't get caught by mpv and the text stayed in the top left corner.

One suggestion I'd make would be to add a valign and halign parameters to show-text, where you could specify left/right/center and top/bottom/center

Thanks for reading this, I hope this isn't too much of a silly feature request :)

@avih
Copy link
Member

avih commented Sep 8, 2017

show-text supports ASS escape sequences, but you need to first disable ASS escaping before using ASS escape sequences. e.g.:

show-text "${osd-ass-cc/0}{\\an1}${osd-ass-cc/1}hello"

Will display hello at the bottom-left. {\\an1} does that (numbers are like on a numeric keypad, so 5 is middle, 9 is top-right, etc), and the other osd-ass-cc thingies are to disable and then enable ASS escaping.

You can also omit the ${osd-ass-cc/1} part if you know your text doesn't include unintentional ASS escape sequences (so everything after ${osd-ass-cc/0} may contain ASS escape sequences which will be interpreted as such).

You can also use colors, font sizes, etc. See more at https://github.com/libass/libass/wiki/ASSv5-Override-Tags and http://docs.aegisub.org/3.2/ASS_Tags/ .

I think that your \n experiment didn't work because show-text strips leading and trailing white spaces.

@AxelTerizaki
Copy link
Author

Interesting. I didn't know it could take ASS sequences. Guess I should have read the manual better.

However, I tried it out exactly as you made it appear and it doesn't seem to work as expected, mpv displays ${oss-

Here's a screenshot of my app in development. In the bottom right corner I'm running mpv with a background image loaded, and my text appears as is when I send it from my app (I hardcoded your example to try it out, but it should display the message sent to my app's API)

Am I missing something? Is there something I should send to mpv before inputting $ commands in show-text?
capture d ecran 2017-09-08 23 26 12

@avih
Copy link
Member

avih commented Sep 8, 2017

This depends on how you use it.

If you use it at input.conf, then it should work just as I quoted it.

If you use it from a natively loaded script (lua or js), then you need mp.command("<exactly-what-i-quoted>"). Note that mp.command(...) does property expansion. Note that you might need to double the backslashes whenever you use it in a scripting language, though I'm not sure.

Alternatively, if you use mp.commandv("show-text", ...) then it's not property expanded. My guess is that you use some external mpv-node bindings which internally use mp.commandv or equivalent, hence the properties don't get expanded.

However, you can expand the properties yourself with the expand-text command, and it must be invoked as mp.command_native which accepts an array of command name and arguments. I don't know if the framework you use support it.

So you'll have to experiment with different approaches.

My suggestion is to first try it at input.conf and verify that it works. Then try it in mpv in some lua script with mp.command("show-text ...") and verify it works. Then try it with mp.commandv("show-text", mp.command_native({"expand-text", "<the escape string>"})) and verify that it works. Then try to figure out how to invoke it from your framework.

@AxelTerizaki
Copy link
Author

I see :) Thanks for the info about properties expansion. I'll look into it as you said, and see how the framework I use works.

For info it's node-mpv :
https://github.com/00SteinsGate00/Node-MPV

I suppose the issue can be closed now, I should be able to position my text as I see fit with this information.

Thank you.

@avih
Copy link
Member

avih commented Sep 9, 2017

Hmm.. if you use it externally it could be difficult, since the value which is the expanded ${osd-ass-cc/0} (and /1) is not a valid UTF8 string, so you might have issues storing/using it.

I'd suggest to write your own mpv-lua script to be used as a proxy (listens to script-message) which accepts the string and then uses it like I mentioned above. And from your own script you'll send a command like maybe script-message show-ass <string which uses ASS sequences>

@AxelTerizaki
Copy link
Author

@avih In my understanding, script-message is a command that sends messages to all clients, as the doc says, however what you're suggesting is that in my lua/js script passed to mpv that I listen to an event.

The only event I can see that would be triggered by external IPC command is client-message but it is undocumented and used internally, it seems so I have no idea on how to use it.

I tried it via input.conf and it works as advertised, but the show-text command, when used via the IPC doesn't take expansion into account and displays the command as is.

When I send this via IPC :

show-text "${osd-ass-cc/0}{\\an1}${osd-ass-cc/1}hello"

it sends the string parameter of show-text as is : see my screenshot in an earlier comment.

The expected behaviour, to me, would be that show-text via the IPC channel should work just as it does when in the input.conf file, or in a JS/LUA script, where it interprets the ${} parameters and expands it, thus allowing ASS stylizing. Note that we're talking about ASS here but if I wanted to display the filename or the current position on screen, the problem would be the same.

I'll reopen the issue since in my opinion, being able to send text with parameter expansion like I'd need to display ASS should be simpler and work via IPC..

@AxelTerizaki AxelTerizaki reopened this Sep 13, 2017
@avih
Copy link
Member

avih commented Sep 13, 2017

I meant do something like this:

  1. Make sure mpv loads the script myipcproxy.lua (either by putting it at your scripts dir or loading it from the command line) which has the following content:
mp.register_script_message("command-str", function(s)
    mp.command(s)  -- this can do property expansion on s
end)
  1. Assuming you follow the IPC socat example at the manual: https://mpv.io/manual/master/#socat-example, the following command will do what you want:
{ "command": ["script-message", "command-str", "show-text ${osd-ass-cc/0}{\\an9}hello"] }

Or, alternatively, if you want to send it only to this script (doesn't matter much though, unless you have other scripts which register command-str):

{ "command": ["script-message-to", "myipcproxy", "command-str", "show-text ${osd-ass-cc/0}{\\an9}hello"] }

As for expanding text variables, you should read the manual and libmpv headres - not all invocations do property expansion automatically. But you can still do explicit property expansion via the expand-text command, e.g:

{ "command": ["expand-text", "vo: ${current-vo}"] }

which will return the expanded string.

You could do the expansion for ${osd-ass-cc/0} too and then send the result to show-text which should work, however, specifically this property expands to an invalid utf8 sequence (no zeroes, just invalid codepoint), so depending on your framework and language, you might have issues holding the expanded string.

I'm not entirely sure whether or not the IPC mechanism on its own can be used to show unescaped ASS - @wm4 might know more, however, mpv supports scripting too, and with the script proxy above you can execute IPC command which will get property-expansion like it would at input.conf.

@AxelTerizaki
Copy link
Author

I confirm this does work indeed.

I still need to figure out how to use it with node-mpv, because at this moment it won't load the script I prepared with your help.

Thanks a lot for the info, it's very valuable and interesting, now I understand better how the scripting works in mpv.

I still wish there would be a simpler way than making a IPC proxy via a script though.

@avih
Copy link
Member

avih commented Sep 13, 2017

because at this moment it won't load the script I prepared with your help.

There's a load-script command which accepts a script path, which you could use via IPC. Continuing with the socat IPC example:

{ "command": ["load-script", "./myipcproxy.lua"] }

@avih
Copy link
Member

avih commented Sep 14, 2017

Huh, apparently it's much simpler than the above, without requiring a proxy script:

{ "command": ["expand-properties", "show-text", "${osd-ass-cc/0}{\\an9}hello"] }

I actually tried the expand-properties prefix before, but couldn't get it working. Apparently I did something wrong, because it does work.

Shall we close the issue?

@AxelTerizaki
Copy link
Author

Oh yes, I confirm this works. I cannot send ASS commands through my own app, but it works if I hardcode the ASS commands in the code for now and leave the message itself to my API. Looks like I'll be able to live with that.

I'll be trying a few things first and will close the issue a bit later, if that's okay. Just to make sure this does what I wish it does. :)

Thanks for your immense help @avih !

@AxelTerizaki
Copy link
Author

Okay, made it work flawlessly after I figured out how to use all ASS features or almost. The libass documentation looks a bit unclear, but the aegisub one is much simpler.

It fits my needs as is, I can display stylized text in the corner of the screen during the first 8 seconds of playback, for example :

capture d ecran 2017-09-14 11 44 40

These are variables in a database, so it works as I originally intended it to :)

Here's an example ASS string for it in JS :

kara.infos = '{\\bord0.7}{\\fscx70}{\\fscy70}{\\b1}'+series+'{\\b0}\\N'+__(kara.songtype+'_SHORT')+kara.songorder+kara.title+'\\N{\\i1}{\\fscx50}{\\fscy50}'+__('REQUESTED_BY')+' '+requester+'{\\i0}';

My only "complaint" would be that you can't send two show-text commands one after the other, the second one cancels the first one, even if the text displayed on screen is different or positioned elsewhere, but I guess I'm being greedy now, aren't I? :)

This issue can be closed unless someone wants to follow-up on the show-text commands canceling each other?

@avih
Copy link
Member

avih commented Sep 14, 2017

pfff... all this for persona 5? good thing (for you) you didn't say it earlier ;)

So, good to close? :)

@AxelTerizaki
Copy link
Author

Haha :)

Yes, will close it now, thank you again for your invaluable help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants