Last active
August 24, 2025 21:10
-
-
Save m-bartlett/58001ccce3a30816008a44360e67b4d5 to your computer and use it in GitHub Desktop.
mpv script which modifies rotates the current video file based on player rotation. Uses ffmpeg to update rotation metadata to avoid re-encoding the video.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is an example of what you could add to your ~/.config/mpv/input.conf file to make use of this script. | |
# ctrl+r will cycle through rotations for the playback of the video. Rotate the video to the desired orientation. | |
# shift+r will invoke the 'ffmpeg-rotate' function from lua script to update the playback rotation of the file permanently. | |
ctrl+r cycle_values video-rotate 90 180 270 0 | |
R script-message ffmpeg-rotate |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- This file should go in ~/.config/mpv/scripts/ | |
local function run_command_sync(command_args) | |
-- Run a subprocess synchronously, and report any unexpected errors | |
local command = { | |
name = "subprocess", | |
args = command_args, | |
capture_stdout = true, | |
capture_stderr = true, | |
playback_only = false, | |
} | |
local result = mp.command_native(command, 0) | |
if not (result.error == nil or result.error == "success") then | |
mp.msg.error("Subprocess failed: " .. tostring(result.error)) | |
if result.stderr then | |
mp.msg.error("Stderr: " .. result.stderr) | |
end | |
end | |
end | |
local function ffmpeg_rotate() | |
local rotation = mp.get_property_number("video-params/rotate") | |
-- convert video rotation (clockwise) to counter-clockwise for ffmpeg | |
if rotation == 270 | |
then rotation=90 | |
elseif rotation == 90 | |
then rotation=270 | |
end | |
local file_path = mp.get_property("path") | |
local file_name = mp.get_property("filename") | |
local tmp_file = "/tmp/"..rotation.."_"..file_name | |
local ffmpeg_args = { | |
"ffmpeg", | |
"-y", | |
"-loglevel", "fatal", | |
"-display_rotation", tostring(rotation), --this flag does the magic, only in somewhat recent versions | |
"-i", file_path, | |
"-codec", "copy", --avoid re-encoding to make the rotation fast | |
tmp_file | |
} | |
--replace the original file with the rotated file | |
local mv_args = {"mv", tmp_file, file_path} | |
run_command_sync(ffmpeg_args) | |
run_command_sync(mv_args) | |
mp.set_property("video-rotate", 0) | |
mp.commandv("video-reload") | |
mp.commandv("playlist-play-index", "current") | |
mp.osd_message("Set "..file_name.." rotation to "..rotation) | |
end | |
mp.register_script_message("ffmpeg-rotate", ffmpeg_rotate) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment