Extract DVD subtitles programmatically - ruby

I'm trying to extract subtitles from unencrypted DVDs with a program, so I can save them seperately. I know there are programs that do that (I found this page for example: http://www.bunkus.org/dvdripping4linux/en/separate/subtitles.html), but I would like to be able to do it with a library call or something like that (do libdvdread or libdvdnav support this), preferably using ruby.

You can have a look at Handbrake, it allows you to extract video, audio and subtitles.
There is also the Handbrake manual here, and the subtitles section here, that can provide more information.
This isn't in Ruby but you should be able to call the Handbrake CLI from Ruby without any problems.

I don't know of any library, which would be able to do this.
In ruby you can call programs. For example to get a directory listing you can do
files= `ls "#{dir}"`.to_a
The backtick variant gives you stdout of the calle program.
To know wheter a file exists
system("ls \"#{file}\"")
The system variant tells you whether the return value of the called program was 0.
Using this two methods, you can do almost anything with noninteracitve programs. The programs described in http://www.bunkus.org/dvdripping4linux/en/separate/subtitles.html seme to be suitable for this kind of control.
Be carefull with escaping arguments you give to external programs. If an argumend is "; rm -rf *; ls ". undesirable things may happen.

Related

How can I make my terminal text rainbow colored upon every boot up? (with lolcat)

I've been wondering how I could do some of these cool customization options for the terminal on a Mac and I came across lolcat.
However, I can't seem to find an answer as to how to add this into my bashrc (FYI: I'm using zsh now just in case that makes a difference as to which file to add my customizations in) I have tried what many others have suggested, which was just typing zsh | lolcat into the terminal to get rainbow output in the current session, but I was wondering how I can have this every time I start a terminal session.
Also, I'm not sure if this is a bug or if there's something wrong with my terminal settings, but when I use a command with lolcat, I get an output like this:
karenlee#Karens-MBP ~ % Documents
Downloads
Library
Movies
Music
Pictures
Postman
Public
38;5;48m
karenlee#Karens-MBP ~ % 38;5;48m
The colors look right, but as you can see, when I type the ls command on the command line, it disappears and the output also gets messy. It also seems like there's extra lines of 38;5;48m which are appearing. And it also seemed like many of the gems that are installed with lolcat have deprecated; is there another alternative to lolcat that plays nicely with macOS Catalina?
I made a shell extension for the world's fastest website generator that I make called Nift. It has an easter egg where you can turn on lolcat output for most things with lolcat.on (after starting the shell with eg. nift sh). You will even get rainbow output when pressing tab to get possible completion options, I doubt you get that with any other suggested solutions.
The shell extension is for f++ which is the in-built scripting language, which has these functions and these types available. But anything it doesn't recognise is run as a system call using the (probably primary/default) shell on your machine (hence calling it a shell extension in REPL shell mode).
Nift will look for a version of lolcat installed on your machine and otherwise use an in-built version of it which should be the world's fastest (it's near identical to my c++ implementation lolcat-cc which is the world's fastest). I highly recommend installing lolcat-cc (or another version of lolcat) on top of Nift though as otherwise you are frequently running the ~5mb Nift binary for basically all system calls, instead of a <1mb binary for lolcat.
f++ is somewhat of an interesting scripting language as well. Take this script for example which creates and deletes 100k empty text files. On my machine this runs in ~3.5 seconds whereas this Bash script doing essentially the same thing takes more like 3 minutes!! Some of the cool things you might already notice from that f++ script is you can expand variables inside strings, you can define variables with types, you can expand variables in to multiple parameters with function calls, you can have LOTS more than 10k input parameters for function calls (should be able to have millions!).
You can find some more information about the Nift REPLs (including shortcuts for different platforms) here.
If you need to define shell variables (not through f++ but the underlying shell) then you will need to do blocks of code using the sys/system function. You can also do blocks of code for Lua(JIT) and ExprTk similarly as they are both embedded in to Nift. You can use both Lua and ExprTk with accessing/modifying f++ variables as well..
So to get this shell (extension). Install Nift through a package manager or clone, make and install off GitHub. Enter nift sh in to your terminal to start the Nift f++ shell extension, then enter lolcat.on to turn on rainbow output.

MediaInfo CLI (Command Line Interface) Syntax Teaching Me Once & For All

Dear Friends at Stack Overflow,
There is a pattern of questioning here that I noticed in many categories, but for the sake of this topic I'll talk about MediaInfo CLI. The same type of questions keep re-occurring because the source problem is NOT solved, which is to teach people how to fish, rather than feeding them with fish.
Some people ask:
"I do not know how to get BitRate only from MediaInfo". They are respected, and the advanced users who answer them are also respected. Others ask the same question for FrameRate, Duration, & Resolution... I respect them, and also respect those who answer them.
However, I'm truly sorry for this process to be redundant. Unfortunately the MediaInfo website documentation does not clarify how to properly use MediaInfo.exe with the CLI version to extract specific information, and the --Info Parameters just lists a lot of parameters without instructing how to use them.
So in order to extract specific information for a video using MediaInfo.exe CLI, I'll just have to kindly ask here because I am unable to customize the parameters myself, since I don't get the syntax on the documentation. I would have taken the easy way to just ask you what kind of information I need to extract from the video, but then every one who doesn't know the syntax will come back asking for redundant questions.
Instead, I decided to waste a bit more of your time by writing all this, in hopes that you will help me and everyone else who will come searching for this specific question on How to Use the MediaInfo CLI --Info-Parameters Syntax so that the answers aren't repeated for every custom inquiry.
I honestly want to understand how to use it, and not just copy pasting the ready made one-line answers I will receive.
I'll start by mentioning what I know, that any new inquirer may learn from the very little I know, and then I'll kindly ask you to teach me how to write proper MediaInfo --Info-Parameters syntax to extract specific video information.
After you Download MediaInfo the CLI version for Windows, extract the zip file and put it on your Desktop.
RUN + CMD
Navigate to the MediaInfo Folder on the Desktop.
Put some Video files in the MediaInfo folder.
Run the following on the terminal:
MediaInfo.exe --help >Help.txt
MediaInfo.exe --Info-Parameters >Info_Parameters.txt
Now you have some help files to search for your required information. The rest of this simple documentation depends on the generosity of my fellow StackOverflow members.
To be more clear about my question, once and for all: How can I write proper syntax for the MediaInfo.exe CLI to extract specific information such as FrameRate, Duration, & Resolution? I need to understand the syntax more than the ready-made solution to be able to customize it later.
Thank you for your time!
When you run mediainfo --Info-Parameters, you will notice that there are seven sections: General, Video, Audio, Text, Other, Image, and Menu. Each of these sections contains many different parameters that contain various information about the file and get called with the format --Output=SectionName;%Parameter%. You can pick multiple parameters from the same section name, separating them with any text you like (including \n for newlines (but not \t for tabs, interestingly)), like --Output=SectionName;%Parameter1%\n%Parameter2%.
You can also add your own text, which gets displayed as however you wrote it, allowing you to label the output for easier reading later. For example, to get the file name, duration, and file size, you can use the command mediainfo --Output="General;File Name: %FileName%\r\nDuration: %Duration/String3%\r\nSize: %FileSize/String%" video.mkv
If you want to get data from multiple sections (like adding video dimensions to the above information), you will have to use a template, as there is no way to get data from multiple sections in the same --Output command and having multiple instances of --Output cancel each other out until you get left with the last one in the list. In the template, specify one section per line and add the parameters to their respective sections, like this:
General;File Name: %FileName%\r\nOverall Bit Rate: %OverallBitRate/String%\r\nDuration: %Duration/String3%\r\nFormat: .%FileExtension%\r\nSize: %FileSize/String%\r\n
Video;Dimensions: %Width%x%Height%\r\n
These parameters will be displayed in the order that they were written in the template, and you cannot go back and forth between sections (in this example, I couldn't add more General parameters after the Video section). To call a template, use the syntax mediainfo --Output=file://template.txt video.mkv or mediainfo --Output=file://C:\full\path\to\the\template.txt video.mkv.
This is also possible on the command line:
mediainfo --Output=$'General;File Name: %FileName%\\r\\nOverall Bit Rate: %OverallBitRate/String%\\r\\nDuration: %Duration/String3%\\r\\nFormat: .%FileExtension%\\r\\nSize: %FileSize/String%\nVideo;\\r\\nDimensions: %Width%x%Height%\\r\\n' input.file
Note the "\n" between the sections
Tested on Ubuntu 18.04 MediaInfo Command line,
MediaInfoLib - v17.12
These days I came across a command line tool called jq. This tool uses filters to manipulate json data like if you are querying a Database.
It seems to me that this tool could be a perfect companion for mediainfo capability of outputting JSON.
Certainly mediainfo parameters are difficult to use but most of us knows how to handle json. Time will be best spent learning jq's filter language than deciphering cryptic mediainfo parameter options ;)
Workflow is more or less like this.
Know what info you want to extract from media file.
Use jq and its filters to extract it.
Commands
See all info on media file in a pretty formatted json
#> mediainfo --output=JSON myVideo.mp4 | jq .
Customize jq filters to get the desired result.
#> mediainfo myVideo.mp4 --output=JSON | jq '.media.track[1] | {FrameRate: .FrameRate, Duration: .Duration, Width: .Width, Height: .Height}'
Extracted info...
{
"FrameRate": "30.000",
"Duration": "158.334",
"Width": "320",
"Height": "176"
}
Possiibilities are endless once you get familiar with jq's filters.

How do you set up tab autocompletion (for directories) in a Ruby CLI program?

Background on what I'm trying to do:
I've been teaching myself Ruby, and as a test project I'm creating a .csv converter. It's working well over all, but what I'm stuck on is allowing the user to easily select the file to be imported. Right now I prompt for the file path with the following code:
def find_original_path
puts "\nWhere is the file that you would like to convert?"
print ">> "
#original_path = gets.chomp
if File.exists?(#original_path)
# Verify that file is a .csv
check_original_type()
else
puts "\nSorry, that file doesn't seem to exist."
# Ask for a new path to file
find_original_path()
end
end
What I'd like to do:
So this works, but it requires that the user know the exact path to their .csv. What I'd prefer is to allow the user to use bash style auto-completion to find their file. Typing ~/ should start off at the user's home directory, and then hitting tab twice should list all available folders/files and so on.
What I've found:
Readline: My understanding is that this module only works for pre-set lists.
Thor: Awesome module, but seems to only work for providing deep argument functionality (e.g. git commands).
Shoes (and variants): Apparently green_shoes in particular has an easy way of doing this, but I'm not yet looking to put a GUI on this tool.
Ruby's Std-lib: I've gone through FileUtils, File, IO, etc...
Backticks and Open4: Makes sense for commands like ls, but not sure about directories.
In Sum:
Haven't found an answer that stood out to me in any of these. I feel like the answer to my problem is either more complex than I realized, or all of my reading has me missing something that's right under my nose. I'm hoping it's the latter, though please be gentle if it's really blindingly obvious :D
Any advice?

Passing shell commands parameters securely with %x[] in Ruby

Let's say I have in a Rails controller:
dir = params[:dir]
output = %x[ls #{dir}]
This is a HUGE security hole if somebody posts dir="foo; rm -rf /"
So I need to secure the parameter. I know I could do
system "ls", dir
But this method does not capture stdout !
So, how can I securely pass parameters to %x[] ?
The problem is that %x() basically hands a string to the shell to be parsed so you'd have to escape everything that the shell could possibly interpret. So %x is pretty much out the window if you need to deal with anything that you haven't built yourself (and event then it is suspect).
One solution is to use Open3.capture3:
out, err, status = Open3.capture3('/bin/ls', dir)
and then deal with the standard output (out) and standard error (err) returns as needed. There are a few other things in Open3 that might serve your needs better.
Have you looked at Ruby's safe levels?
http://www.ruby-doc.org/docs/ProgrammingRuby/html/taint.html
For levels >= 2 it says "Can't change, make, or remove directories, or use chroot."
There also used to be a sandbox gem, but I'm not sure if that's still active. You also could have a look at the source of "Try Ruby!" there has to be some kind of sandboxing in there.

Programmatically hiding many files when creating hybrid iso with hdiutil

I'm trying to script the creation of a hyrbid (iso/joliet/hfs) iso with hdiutil. I can, for example, build an iso that hides things on the mac side like so:
hdiutil makehybrid -o foo.iso -hfs -joliet -iso -hide-hfs "{foo/bar.txt,foo/other.rtf}" foo
That's just an example of course, but the point is I can get it to hide say seven or eight example files I specify like that, with spaces in the filenames and verious dots and underscores.
But for my actual real-deal script I need to list in the neighborhood of 70 files, which does not seem to work when I test it. The whole string is being passed in correctly, I know this because when you turn on '-verbose' it prints the string and says it doesn't match anything.
So my best guess is it has something to do with the length of the string passed in, but I don't see anything in the docs indicating that. Any ideas? Think it's a bug? An alternative way of accomplishing this?
This is on Mac OS X 10.5.8, btw.
Two [UPDATE, make it Three] (untested) suggestions:
use the -plistin option to
specify all the parameters;
(better) try organizing the files to be
hidden into directories, if
necessary, so you can easily hide
them by directory-specific globs
rather than having to spell out each
file.
[UPDATE] you could try using mkisofs from cdrtools to make the ISO image. MacPorts has a supported port of it. It could be that the code in hdiutil was originally based on an earlier version. In any case, you have the advantage of access to the source code and perhaps figuring out what the limitations are.
P.S. There seems to be a couple of minor nits with the MacPorts port. In particular, the
man pages are installed in the wrong directory. [UPDATE: fixed in 3.00_1]

Resources