Filename: Private: No Yes Filetype: Auto ABAP Sophia Apex Azure CLI Batch Bicep C Cameligo Clojure CoffeeScript C++ C# CSP CSS Cypher Dart Dockerfile ECL Elixir Flow9 FreeMarker2 FreeMarker2 (Angle/Bracket) FreeMarker2 (Angle/Dollar) FreeMarker2 (Auto/Bracket) FreeMarker2 (Auto/Dollar) FreeMarker2 (Bracket/Bracket) FreeMarker2 (Bracket/Dollar) F# Go GraphQL Handlebars Terraform HTML Ini Java JavaScript Julia Kotlin Less Lexon Liquid Lua Modula-3 Markdown MDX MIPS DAX MySQL Objective-C Pascal Pascaligo Perl PostgreSQL PHP Plain text ATS PQ PowerShell Protobuf Pug Python Q# R Razor Redis Redshift ReStructuredText Ruby Rust Small Basic Scala Scheme Sass Shell Solidity SPARQL SQL StructuredText Swift SV Tcl Twig TypeScript TypeSpec Visual Basic V WebGPU Shading Language XML YAML Indentation: Spaces Tabs 1 2 3 4 5 6 7 8 Clone #!/usr/bin/env ruby require 'optparse' require 'json' require 'cgi' require 'net/http' require 'shellwords' DEFAULT_ADDRESS = 'http://127.0.0.1:8080' DEFAULT_PASSWORD = 'password' class VLSub attr_accessor :address, :password, :subs def initialize(options, subs) @address = options[:address] @password = options[:password] @subs = subs end def run! subs.each do |sub| vlc!(command: 'addsubtitle', val: File.realpath(sub)) end idx = streams!.keys.map { |k| k.gsub(/^Stream\s+/, '').to_i }.sort.last return unless idx vlc!(command: 'subtitle_track', val: idx.to_i) rescue => e msg = "Error loading subtitles\n\n#{e}\n\n#{e.backtrace[0..5].join("\n")}" $stderr.puts msg cmd = "notify-send -e -t 0 -u critical #{Shellwords.escape(msg)}" system(cmd) exit!(1) end private def streams! vlc!; streams end def streams vlc['information']['category'].select { |k| k.start_with?('Stream') } end def vlc!(query = {}) remove_instance_variable(:@vlc) rescue nil vlc(query) end def vlc(query = {}) @vlc ||= begin url = "#{address}/requests/status.json?#{to_query(query)}" uri = URI.parse(url) Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http| begin request = Net::HTTP::Get.new("#{uri.path}?#{uri.query}") request.basic_auth('', password) response = http.request(request) response.error! unless response.is_a?(Net::HTTPSuccess) response end while response.is_a?(Net::HTTPRedirection) JSON.parse(response.body) end end end def to_query(hash) hash.map { |k, v| encode_query(k, v) }.join('&') end def encode_query(key, value) case value when Hash then value.map { |k, v| encode_query("#{key}[k]", v) }.join('&') when Array then value.map { |v| encode_query("#{key}[]", v) }.join('&') when nil then '' else "#{key}=#{CGI.escape(value.to_s).gsub('%2F', '/')}" end end end options = { address: DEFAULT_ADDRESS, password: DEFAULT_PASSWORD, } parser = OptionParser.new do |o| o.banner = "Usage: #{$PROGRAM_NAME} [options] <file.srt...>" o.separator '' o.separator 'Specific options:' o.on('-aADDRESS', '--address=ADDRESS', "Set VLC address (default: #{DEFAULT_ADDRESS})") do |value| options[:address] = value end o.on('-pADDRESS', '--password=ADDRESS', "Set VLC password (default: #{DEFAULT_PASSWORD})") do |value| options[:password] = value end o.separator '' o.separator 'Common options:' o.on_tail('-h', '--help', 'Show this message and exit') do puts o exit! end end args = parser.parse!(ARGV) if args.empty? $stderr.puts "#{$0}: wrong number of arguments (given #{args.length}, expected 1+)" $stderr.puts $stderr.puts parser exit!(1) end VLSub.new(options, args).run! Paste