summaryrefslogtreecommitdiff
path: root/mpv/scripts/music-mode.lua
blob: 4c57456ee5c3c82523bb0c8bb18ae8c8e631625c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
local mp = require 'mp'
local msg = require 'mp.msg'
local opt = require 'mp.options'

--script options, set these in script-opts
local o = {
    --change to disable automatic mode switching
    auto = true,

    --profile to call when valid extension is found
    profile = "music",

    --runs this profile when in music mode and a non-audio file is loaded
    --you should essentially put all your defaults that the music profile changed in here
    undo_profile = "",

    --start playback in music mode. This setting is only applied when the player is initially started,
    --changing this option during runtime does nothing.
    --probably only useful if auto is disabled
    enable = false,

    --the script will also enable the following input section when music mode is enabled
    --see the mpv manual for details on sections
    input_section = "music",

    --dispays the metadata of the track on the osd when music mode is on
    --there is also a script message to enable this seperately
    show_metadata = false
}

opt.read_options(o, 'musicmode', function() msg.verbose('options updated') end)

--a music file is one where mpv returns an audio stream or coverart as the first track
local function is_audio_file()
    local track_list = mp.get_property_native("track-list")

    local has_audio = false
    for _, track in ipairs(track_list) do
        if track.type == "audio" then has_audio = true
        elseif not track.albumart and (track["demux-fps"] or 2) > 1 then return false end
    end
    return has_audio
end

local metadata = mp.create_osd_overlay('ass-events')
metadata.hidden = not o.show_metadata

local function update_metadata()
    metadata.data = mp.get_property_osd('filtered-metadata')
    metadata:update()
end

local function enable_metadata()
    metadata.hidden = false
    metadata:update()
end

local function disable_metadata()
    metadata.hidden = true
    metadata:remove()
end

--changes visibility of metadata
local function show_metadata(command)
    if command == "on" or command == nil then
        enable_metadata()
    elseif command == "off" then
        disable_metadata()
    elseif command == "toggle" then
        if metadata.hidden then
            enable_metadata()
        else
            disable_metadata()
        end
    else
        msg.warn('unknown command "' .. command .. '"')
    end
end

--to prevent superfluous loading of profiles the script keeps track of when music mode is enabled
local musicMode = false

--enables music mode
local function activate()
    mp.commandv('apply-profile', o.profile)
    mp.commandv('enable-section', o.input_section, "allow-vo-dragging+allow-hide-cursor")
    mp.osd_message('Music Mode enabled')

    if o.show_metadata then
        show_metadata("on")
    end

    musicMode = true
end

--disables music mode
local function deactivate()
    mp.commandv('apply-profile', o.undo_profile)
    mp.commandv('disable-section', o.input_section)
    mp.osd_message('Music Mode disabled')

    if o.show_metadata then
        show_metadata('off')
    end

    musicMode = false
end

local function main()
    --if the file is an audio file then the music profile is loaded
    if is_audio_file() then
        msg.verbose('audio file, applying profile "' .. o.profile .. '"')
        if not musicMode then
            activate()
        end
    elseif o.undo_profile ~= "" and musicMode then
        msg.verbose('video file, applying undo profile "' .. o.undo_profile .. '"')
        deactivate()
    end
end

--sets music mode from script-message
local function script_message(command)
    if command == "on" or command == nil then
        activate()
    elseif command == "off" then
        deactivate()
    elseif command == "toggle" then
        if musicMode then
            deactivate()
        else
            activate()
        end
    else
        msg.warn('unknown command "' .. command .. '"')
    end
end

local function lock()
    o.auto = false
    msg.info('Music Mode locked')
    mp.osd_message('Music Mode locked')
end

local function unLock()
    o.auto = true
    msg.info('Music Mode unlocked')
    mp.osd_message('Music Mode unlocked')
end

--toggles lock
local function lock_script_message(command)
    if command == "on" or command == nil then
        lock()
    elseif command == "off" then
        unLock()
    elseif command == "toggle" then
        if o.auto then
            lock()
        else
            unLock()
        end
    else
        msg.warn('unknown command "' .. command .. '"')
    end
end

--runs when the file is loaded, if script is locked it will do nothing
local function file_loaded()
    if o.auto then
        main()
    end
end

if o.enable then
    activate()
end

--sets music mode
--accepts arguments: 'on', 'off', 'toggle'
mp.register_script_message('music-mode', script_message)

--stops the script from switching modes on file loads
----accepts arguments: 'on', 'off', 'toggle'
mp.register_script_message('music-mode-lock', lock_script_message)

--shows file metadata on osc
--accepts arguments: 'on' 'off' 'toggle'
mp.register_script_message('show-metadata', show_metadata)

mp.add_hook('on_preloaded', 40, file_loaded)
mp.observe_property('filtered-metadata', 'string', update_metadata)