I am adding a subtitle file to a video using MP4Box. The following command works perfectly from the command line:
c:/GPAC/MP4Box -add c:/test.m4v#audio -add c:/test.m4v#video -add c:/test_en.srt:hdlr=sbtl:lang=en:group=2:layer=-1 -new c:/test2.m4v
However, what I really want to do is to put the command into a .bat file. The following is my command in the batch file:
%1/GPAC/MP4Box -add %2/%3#audio -add %2/%3#video %4 -new %2/%3
As you can see I am trying to pass in "-add c:/test.m4v#video -add c:/test_en.srt:hdlr=sbtl:lang=en:group=2:layer=-1" as the fourth parameter. The reason I want to do this is there may be many subtitles files being added:
"-add c:/test.m4v#video -add c:/test_en.srt:hdlr=sbtl:lang=en:group=2:layer=-1 -add c:/test.m4v#video -add c:/test_ja.srt:hdlr=sbtl:lang=ja:group=2:layer=-1:disabled"
so I don't know ahead of time how many -add commands there need to be so I want to just pass them all in as one parameter. But, mp4box doesn't like this.
I'm not sure if this is a limitation with mp4box or with batch file parameters in general.
I know this is an old thread, but for anyone searching in future.
I used the following approach in a batch file, combined with filemenu tools to allow for a simple right-click menu function to initiate the batch process:
for %%a in (*.m4v) do mp4box -add "%%~Na.eng.srt":lang=eng:layout=0x60x0x-1:group=2:hdlr="sbtl:tx3g" "%%a"
I ended up solving this by writing/rewriting the batch file from code every time I needed to run it. So I would create the batch file with all my arguments. Run it. Then delete the file. This worked great.
Batch files on Windows are quirky and have limited functionality. What you could do is use Cygwin, which allows you to use a real shell (like Bash for example) on Windows.
A note regarding MP4Box syntax,since both the question and the answers here have it... "suboptimally", let's just say.
If you want MP4Box to rewrite an input file — which is its default mode, unless told otherwise — while adding subtitles (or any other tracks/metadata), you should specify the file to be modified first on the command line, and without using -add. So, to rewrite a video file my_video.mp4 with subtitled added from my_video_English.srt and my_video_German.srt, you'd use:
MP4Box my_video.mp4 \
-add my_video_English.srt \
-add my_video_German.srt
No need to specify tracks, since you want to use all available tracks from all input files. (Here also, that's the default disposition for track data.)
MP4Box will create a new temporary output file, copy the contents of my_video.mp4 into it, remuxing the original tracks with new tracks created for each subtitle file, and then rename the temporary file back to my_video.mp4, overwriting the original. (If you don't want to overwrite, add -out newname.mp4 to the end of the command line.)
The program help (specifically, MP4Box -h import) especially warns against adding subtitle tracks to the output stream before any video tracks are created, so -add foo.srt should never be before the a/v input file on the command line:
$ MP4Box -h import
[...]
Note: When importing SRT or SUB files, MP4Box will choose
default layout options to make the subtitle appear at the
bottom of the video. You SHOULD NOT import such files before
any video track is added to the destination file, otherwise
the results will likely not be useful (default SRT/SUB
importing uses default serif font, fontSize 18 and display
size 400x60). For more details, check TTXT doc.
It's possible this wouldn't affect file rewriting (because, the video track is already in the output stream before it even begins), but it definirely would affect use of -out. In general, placing the input a/v content first in the arguments is just a good habit to get into when using MP4Box.
Related
I made this script below to make a backup of some files. It works fine, but i wanted make a list for the files that need be skipped from compressing.
For example:
my list.txt has all the files that will be compressed. But i wanted to make another list for the files that need be skipped, like exclusion_list.txt. Actually i put all files that i want be ignored from compressing into the command line, as shown below -x*\Test1 -x*\Test2.
But i really wanted to make a exclusion list for not keep changing the command line everytime i need to exclude a file or folder.
How i can do it?
"%winrar%\winrar.exe" a -x*\Test1 -x*\Test2 -ibck -ep1 -ilog%userprofile%\Desktop\log.log "compressed %date:/=.%.rar" "#list.txt"
From the documentation: the exclusion option -x also supports a list file when it is preceded by #:
"%winrar%\winrar.exe" a -x#exclusion_list.txt -ibck -ep1 -ilog%userprofile%\Desktop\log.log "compressed %date:/=.%.rar" "#list.txt"
with the file exclusion_list.txt containing:
*\Test1
*\Test2
By the way, there is even a console version of WinRAR, called rar.exe, which is a non-GUI version.
I scheduled a .cmd file that would convert a network stream into a .mp4 file, using:
vlc -vvv "http://86.127.212.113/control/faststream.jpg?stream=mxpeg" --sout=#transcode{vcodec=h264,scale=Automat,scodec=none}:file{dst=C:\\Users\\ACV\\Videos\\rec3.mp4,no-overwrite} :no-sout-all :sout-keep
It often works, but sometimes it just creates big files that I am not able to play.
Even VLC itself cannot play these files, outputting just this
I would suggest that you use the following syntax:
Replace the = after --sout with a space character
Doublequote the --sout chain
Replace the prefix : characters for the global options for no-sout-all and sout-keep with --
#"%ProgramFiles%\VideoLAN\VLC\vlc.exe" -vvv "http://86.127.212.113/control/faststream.jpg?stream=mxpeg" --sout "#transcode{vcodec=h264,scale=Automat,scodec=none}:file{dst=C:\\Users\\ACV\\Videos\\rec3.mp4,no-overwrite}" --no-sout-all --sout-keep
I have included the full path to vlc.exe for safety, please adjust it as you need.
I have many many pdf files in a directory that I need to convert from pdf to png. Currently, I am using the ImageMagick command:
magick mogrify -format png *.pdf
Because, there are so many files, I would like to use ghostscript directly because there are several sources that suggest that I could achieve a 75% reduction in processing time by doing this.
However, I am having trouble finding a clean dos command example to accomplish the same thing as the ImageMagick command above. I believe I need to execute the gswin64c.exe module but I am unsure how to do this to accomplish what I need to get done. Can someone provide me with a clean example of the ghostscript that accomplishes what I'm doing in ImageMagick?
After much digging, what I discovered was that ghostscript does not really have a wildcard that would allow reference to all files of a certain pattern (like ImageMagick does). To convert all files in a directory that are pdf's to png's, a dos script like the following could be used:
for %%x in (*) do gswin64c.exe -sDEVICE=png16m -dBATCH -dNOPAUSE -dQUIET -
SOutputFile="%%~nx.png" %%~nx.pdf
This can also be run from the command line by simply using single percentage signs (%) instead of the double percentage signs in the script above.
The terms are as follows:
gswin64c.exe: This is the dos command version of GhostScript. It should be used as opposed to gswin64.exe which will open a GhostScript window.
-sDEVICE=png16m This indicates the form of the output file. Is this case png.
-dBATCH -dNOPAUSE. These are GhostScript options and when employed will allow for continuous operation of the script (without them, the program will pause after each file converted).
-dQUIET - This suppresses notifications that display on stdout after each processed file.
SOutputFile="%%~nx.png" %%~nx.pdf This indicates the pattern for the input files and the output files. x is the loop variable. The % sign is used as a wild card. ~nx is a Dos convention which truncates the extension of an echoed file name.
Question:
Can inotify be used to reliably record files in a [linux] system?
Details:
I am attempting to use inotifywait to track users movements (currently using bash, but it has been suggested that I migrate to a scripting language). Ultimately I want to add new files to a database upon creation (create, moved_from), update existing rows in a database upon file modification (modify, attrib, move_to), and finally remove a row upon file deletion (delete). I am, however, running into many problems as even an action as seemingly simple as save, generates many inotifywait messages. Observe the following commands and their output (note, the use of /home/user/ is purely for example purposes):
Examples:
Example 1: Listen for file creation:
$ inotifywait -mr /home/user/ -e create --format %w:%f:%e:%T --timefmt %T
Touch:
$touch test.txt
/home/user/:test.txt:CREATE:21:35:30
Open a new file with vim then issue :w command:
$vim test2.txt
/home/user/:test2.txt:CREATE:21:35:30
Open an existing file with vim then issue :w command:
$vim test2.txt
/home/user/:4913:CREATE:21:35:30
/home/user/:test2.txt:CREATE:21:35:30
Open a new file with gedit then click save:
$gedit test3.txt
/home/user/:test3.txt~:CREATE:21:35:30
Open an existing file with gedit then click save:
$gedit test3.txt
/home/user/:.goutputstream-HN3ZDW:CREATE:21:35:30
/home/user/:test3.txt~:CREATE:21:35:30
Note that not only are two new files displayed as having ben created (4913 and .goutputstream-HN3ZDW), but also that the only file being created is test3.txt~ and not test3.txt, even though the file test3.txt is created when checked with the ls command. For completeness, here is the above example, but with a few more options.
Example 1: Listen for file creation, modification, deltion, and movement:
$ inotifywait -mr /home/user/ -e create -e modify -e delete -e moved_to -e moved_from --format %w:%f:%e:%T --timefmt %T
Touch:
$touch test.txt
/home/user/:test.txt:CREATE:21:35:30
Open a new file with vim then issue :w command:
$vim test2.txt
/home/user/:test2.txt:CREATE:22:12:32
Open an existing file with vim then issue :w command:
$vim test2.txt
/home/user/:4913:CREATE:22:04:35
/home/user/:4913:DELETE:22:04:35
/home/user/:test2.txt:MOVED_FROM:22:04:35
/home/user/:test2.txt~:MOVED_TO:22:04:35
/home/user/:test2.txt:CREATE:22:04:35
/home/user/:test2.txt~:DELETE:22:04:35
Open a new file with gedit then click save:
$gedit test3.txt
/home/user/:test3.txt~:CREATE:21:35:30
Open an existing file with gedit then click save:
$gedit test3.txt
/home/user/:.goutputstream-0WQ2DW:CREATE:22:06:34
/home/user/:test3.txt~:CREATE:22:06:34
/home/user/:.goutputstream-0WQ2DW:MOVED_FROM:22:06:34
/home/user/:test3.txt:MOVED_TO:22:06:34
Basically my question is "is it possible to use inotify to update a file in a database"? For example, if a user edits a file and saves it, I want it to be reflected in the database as an update to that file, and not a brand new file replacing a completely different file. Any help would be greatly appreciated, even if it's a suggestion pointing me in a different direction.
inotify tells you what happens like it happens.
Gedit, like most editors, saves by first writing a temporary file then moving that file into place. This avoids overwriting the file with a half-written version in case the editor or the whole system crashes while the file is being written. Vim takes a different approach (this can be configured, I won't go into details here — see e.g. why inode value changes when we edit in “vi” editor?): it first creates a temporary backup file, then writes the new file.
If you want these to be recorded as a single editing event, you'll have to perform some pattern recognition on the even log. A create-write-move sequence that replaces an existing file and a create-move-create delete sequence like vim's would be the archetypal patterns. Note that the pattern might be interleaved with other events.
I have a suspicion that there's a better way to do what you want to do, but I don't understand what you're trying to do. If you're trying to log user actions, you have already found a way, but there are simpler ways: loggedfs or the audit subsystem. If you want to keep a backup of all file versions, either hook up the editor to a version control system (this lets users control what gets backed up) or use a versioning filesystem such as copyfs. You can even store the files in the database directly, by using a filesystem like mysqlfs or postgresqlfs (admittedly neither project looks maintained).
I have a folder with a few files in it; I like to keep my folder clean of any stray files that can end up in it. Such stray files may include automatically generated backup files or log files, but could be a simple as someone accidentally saving to the wrong folder (my folder).
Rather then have to pick through all this all the time I would like to know if I can create a batch file that only keeps a number of specified files (by name and location) but deletes anything not on the "list".
[edit] Sorry when I first saw the question I read bash instead of batch. I don't delete the not so useful answer since as was pointed out in the comments it could be done with cygwin.
You can list the files, exclude the one you want to keep with grep and the submit them to rm.
If all the files are in one directory:
ls | grep -v -f ~/.list_of_files_to_exclude | xargs rm
or in a directory tree
find . | grep -v -f ~/.list_of_files_to_exclude | xargs rm
where ~/.list_of_files_to_exclude is a file with the list of patterns to exclude (one per line)
Before testing it make a backup copy and substitute rm with echo to see if the output is really what you want.
White lists for file survival is an incredibly dangerous concept. I would strongly suggest rethinking that.
If you must do it, might I suggest that you actually implement it thus:
Move ALL files to a backup area (one created per run such as a directory containing the current date and time).
Use your white list to copy back files that you wanted to keep, such as with copy c:\backups\2011_04_07_11_52_04\*.cpp c:\original_dir).
That way, you keep all the non-white-listed files in case you screw up (and you will at some point, trust me) and you don't have to worry about negative logic in your batch file (remove all files that _aren't of all these types), instead using the simpler option (move back every file that is of each type).