HarveyDevel / rmeta

Batch renaming of mp4 and mkv "title" field metadata to match filename.
GNU General Public License v2.0
3 stars 1 forks source link

Breaks when using ' in a file name #2

Closed skylinekiller closed 1 year ago

skylinekiller commented 1 year ago

I received the following errors. I tried all and only mp4 john@SpaceGhost:/mnt/p$ rmeta all The file is being analyzed. The changes are written to the file. Done. The file is being analyzed. The changes are written to the file. Done. Unknown command 'set title 'How It's Made s08e01 Photographs; Fur Tanning; Welding Electrodes; Electric Violins'', -h for help.

john@SpaceGhost:/mnt/p$ rmeta mp4 Unknown command 'set title 'How It's Made s08e01 Photographs; Fur Tanning; Welding Electrodes; Electric Violins'', -h for help. Title metadata of How It's Made s08e01 Photographs; Fur Tanning; Welding Electrodes; Electric Violins.mp4 has been changed

It says "has been changed but it has not been changed. Works fine with mkv, but not mp4. Also ran udo apt install kid3-cli mkvtoolnix again to see if that was the issue but it shows its using the latest version

HarveyDevel commented 1 year ago

Yep its a bug. Looks like it occurs because of the ' in It's which breaks the statement early. Unsure how I can sanitise the file name so it does not end prematurely. I will have to think about it.

Until I figure it out you will have to avoid using " or ' in file names.

skylinekiller commented 1 year ago

Thank you for looking into this.

From: Troy Harvey @.> Sent: Monday, June 5, 2023 1:17 AM To: HarveyDevel/rmeta @.> Cc: skylinekiller @.>; Author @.> Subject: Re: [HarveyDevel/rmeta] error using rmeta for mp4 on Windows (Issue #2)

Reopened #2https://github.com/HarveyDevel/rmeta/issues/2.

- Reply to this email directly, view it on GitHubhttps://github.com/HarveyDevel/rmeta/issues/2#event-9431738533, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AESH3BLZNG4ZPQXYV4BFNL3XJW523ANCNFSM6AAAAAAY2NDTVA. You are receiving this because you authored the thread.Message ID: @.**@.>>

HarveyDevel commented 1 year ago

Rewritten in python and added sanitisation of file names. Huge thanks to @dev-ptr for the heavy lifting sorting that out.

skylinekiller commented 1 year ago

I tested it in Windows. I reinstalled using sudo wget -P /usr/bin https://raw.githubusercontent.com/HarveyDevel/rmeta/master/rmeta

Then ran the following that produced the below errors. Nothing was written to the mp4 file

john@SpaceGhost:/mnt/p$ rmeta mp4 Unknown command 'set title 'Citadel's s01e01 The Human Enigma'', -h for help. Title metadata of Citadel's s01e01 The Human Enigma.mp4 has been changed Title metadata of Citadel_s s01e02 Spies Appear in Night Time.mp4 has been changed

If I missed a step or didn't update the new rmeta correctly, please educate me so I can test it further

HarveyDevel commented 1 year ago

My assumption is that because /usr/bin/rmeta already existed it downloaded it to /usr/bin/rmeta.1

So if you could run: sudo rm /usr/bin/rmeta
sudo rm /usr/bin/rmeta.1

sudo wget -P /usr/bin https://raw.githubusercontent.com/HarveyDevel/rmeta/master/rmeta
sudo chmod +x /usr/bin/rmeta

An let me know if it works, if so I'll update the instructions to account for the file already existing.

skylinekiller commented 1 year ago

I didn't receive any errors, but it didn't write the meta to the mp4 files, only MKV files (although the code below is for mp4, I ran a test separately)

john@SpaceGhost:/mnt/p$ rmeta mp4 Title metadata of Citadel s01e01 The Human Enigma.mp4 has been changed Title metadata of Citadel's s01e02 Spies Appear in Night Time.mp4 has been changed john@SpaceGhost:/mnt/p$

For guide purposes, It didn't seem to remove anything, I received the following errors:

`john@SpaceGhost:~$ sudo rm /usr/bin/rmeta [sudo] password for john: rm: cannot remove '/usr/bin/rmeta': No such file or directory john@SpaceGhost:~$ sudo rm /usr/bin/rmeta.1 rm: cannot remove '/usr/bin/rmeta.1': No such file or directory john@SpaceGhost:~$ sudo wget -P /usr/bin https://raw.githubusercontent.com/HarveyDevel/rmeta/master/rmeta --2023-06-07 04:28:57-- https://raw.githubusercontent.com/HarveyDevel/rmeta/master/rmeta Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ... Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 1643 (1.6K) [text/plain] Saving to: ‘/usr/bin/rmeta

rmeta 100%[=================================================>] 1.60K --.-KB/s in 0s

2023-06-07 04:28:57 (42.8 MB/s) - ‘/usr/bin/rmeta’ saved [1643/1643]`

HarveyDevel commented 1 year ago

Unfortunately I can not reproduce the problem. I tried on Linux and Windows using the same file name as in your example and it is working for both mp4 and mkv files.

The only two possible causes I can think of is that either: My WSL is more up to date and one of those package updates fixed an issue so sudo apt update followed by sudo apt upgrade and try again or that the mp4 file being modified is in some way not compliant with the spec. Does it work on other mp4 files?

skylinekiller commented 1 year ago

Ok, ill do more testing on my ND and provide feedback.. Thank you

Sent from my Galaxy

-------- Original message -------- From: Troy Harvey @.> Date: 6/7/23 1:34 PM (GMT-10:00) To: HarveyDevel/rmeta @.> Cc: skylinekiller @.>, Comment @.> Subject: Re: [HarveyDevel/rmeta] Breaks when using ' in a file name (Issue #2)

Unfortunately I can not reproduce the problem. I tried on Linux and Windows using the same file name as in your example and it is working for both mp4 and mk4 files.

The only two possible causes I can think of is that either: My WSL is more up to date and one of those package updates fixed an issue so sudo apt update followed by sudo apt upgrade and try again or that the mp4 file being modified is in some way not compliant with the spec. Does it work on other mp4 files?

— Reply to this email directly, view it on GitHubhttps://github.com/HarveyDevel/rmeta/issues/2#issuecomment-1581654230, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AESH3BMRO7ASEZBXDNLZFI3XKEFWZANCNFSM6AAAAAAY2NDTVA. You are receiving this because you commented.Message ID: @.***>

skylinekiller commented 1 year ago

I did some more testing and it appears to work on some of my encodes and some it doesn't. Hand brake encodes don't seem to have an issue, but when I encode with python script w/Vapoursynth it doesn't write the metadata. I have attached two mediainfo files and the link is for the video file that does not write metadata in case you wanted to test on the actual video Video that did write Metadata.txt Video that did NOT write Metadata.txt

Link to video for testing https://seedbucket.seedboxes.cc/api/share/PlQdQ9nNMzlGPWgoZIqh

HarveyDevel commented 1 year ago

Analysing the video file directly with kid3 kid3 metadata Note Tag 2: MP4 title field.

I assume this was what you wanted it set to before renaming it for upload. But I ran rmeta mp4 and it updated the title to the current filename.

So based on that testing it does appear to work.

skylinekiller commented 1 year ago

That is interesting. I ran it and took screenshots this time. It will change the File title for the Arnonld (Handbrake encode) and also changes the Movie name shown in Media info, but as you can see with the pics, it doesn't change Citadel (Python/Vapoursnth encode, nor does it change it in MediaInfo. I also noted when running the rmeta, it will hang from time to time when it gets to the Citadel. Currently, I use Exiftool, but it's slow and rewrites the entire file. It took 16 hours to do one of my drives. I am only trying to provide input to make the tool more bulletproof or perhaps, in my case, idiot-proof, and I don't mind testing in the Win environment. If this drags things down and creates unnecessary work, I'll stand down. Before running the tool before After running the tool after

HarveyDevel commented 1 year ago

If this drags things down and creates unnecessary work, I'll stand down.

I appreciate you bringing issues to my attention as well as feature requests.

Now I see where the information is not showing up I think I have a better understanding of the issue and did more testing:

metadata comparison

As you can see within VLC on windows and mediainfo through WSL both agree on the metadata having been set. But Windows 11 file properties shows it blank.

So my new assumption is that Windows layers its own file system metadata over the top which Windows Explorer and Microsoft's media player (forget the name) use that data. Where as most other programs just read the files ID3 metadata which is what we are setting with rmeta

I am not a Windows user so I might be way off, but unless anyone has any ideas as to what I can do to improve this situation I am at a loss, sorry.

skylinekiller commented 1 year ago

I just wanted to give some feedback. After multiple testing of other files, it seems to be working without any issues, I musts have had a few unique files where it wouldn't right the metadaa, but since then, I haven't had any issues and its super quick. I prefer to use this over Exif Tool I do have a quick question, is it possible to create a .bat file where I can just double clock and have it start in the P: directory and do a recursive -r all? Or do I need to stary Ubunit and change directory each time?

John

HarveyDevel commented 1 year ago

Thanks for reporting back.

I do have a quick question, is it possible to create a .bat file where I can just double clock and have it start in the P: directory and do a recursive -r all? Or do I need to stary Ubunit and change directory each time?

As it stands currently to use my script on Windows you would have to use WSL.

But with some work it might be possible to have a Windows solution without WSL.

My script makes use of mkvtoolnix for .mkv and kid3 for .mp4 files to do the actual editing. I did a quick search and they appear to make Windows versions of their products.

So you could install those applications and write a script specifically for Windows. No idea how to write that in a Windows batch file (.bat).

Alternatively you might be able to install python, kid3 and mkvtoolnix for Windows. Make sure the directories containing mkvtoolnix and kid3 binaries and my python script are added to system PATH and run my script from Windows command prompt or PowerShell.

I am new to Python (learnt it for the recent changes) not entirely sure of cross platform differences, you might have to make some modifications to my script, could be as simple as kid3-cli becomes kid3-cli.exe

Running Windows 11 in a VM has performed terribly so I am not going to be much help on that front. I have a spare SSD here, if I find time I'll look into its viability an if I can make my script fully compatible without WSL.

EDIT:

and do a recursive -r all?

I suspect you already know this but just in case, the order of arguments matters. So it would be rmeta all -r

skylinekiller commented 1 year ago

Good day, I was finally able to make these work in Python, but I can't get it to open and run with a double click have to run it from a command prompt and type "python rmeta_mpr -r" or whichever file I use. But it does work in windows and your script is way faster than that Exif method.

Let me know if you can get it to launch on a one-click. I didn't spend a whole lot of time, but I will keep trying later.

HarveyDevel commented 1 year ago

G'day. Great to hear you got it working.

Just guessing, but make sure the file has an extension of .py and go to the scripts properties, tell it to open with python.exe

However as -r is an argument passed to the command it would never be recursive. So if you want to run the script by double clicking you would have to make recursive the default option without args.

skylinekiller commented 1 year ago

So are you saying that I have to make edits to the script to either do it in the current directory that's one script and the other script would be recursive that's the only way I can be able to double click it?

Sent from my Galaxy

-------- Original message -------- From: Troy Harvey @.> Date: 6/21/23 3:35 PM (GMT-10:00) To: HarveyDevel/rmeta @.> Cc: skylinekiller @.>, Comment @.> Subject: Re: [HarveyDevel/rmeta] Breaks when using ' in a file name (Issue #2)

G'day. Great to hear you got it working.

Just guessing, but make sure the file has an extension of .py and go to the scripts properties, tell it to open with python.exe

However as -r is an argument passed to the command it would never be recursive. So if you want to run the script by double clicking you would have to make recursive the default option without args.

— Reply to this email directly, view it on GitHubhttps://github.com/HarveyDevel/rmeta/issues/2#issuecomment-1601896285, or unsubscribehttps://github.com/notifications/unsubscribe-auth/AESH3BLPBQWSGNTPMWFI6ALXMOONNANCNFSM6AAAAAAY2NDTVA. You are receiving this because you commented.Message ID: @.***>

HarveyDevel commented 1 year ago

Yep. Keep in mind I do not know what changes you made but based on my script as is running rmeta alone is invalid. It requires an argument (an option) passed to it in order to know what to do. So you would need to modify the logic in order to run with no argument as double clicking doesn't provide you an opportunity to give it an argument.

I'll explain how the code works to help you along.

action_type = sys.argv[1] recursive = False

https://github.com/HarveyDevel/rmeta/blob/master/rmeta#L45

Here we set action_type to hold the first arg (option) passed to rmeta which is located in the index at the position [1]

The only valid args in this position are mp4 OR mkv OR all every thing else is invalid. The very next line sets recursive to a default value of False because we do not always want to perform recursive operations.

if len(sys.argv) > 2 and sys.argv[2] == "-r": recursive=True

https://github.com/HarveyDevel/rmeta/blob/master/rmeta#L47

If there is a second arg (option) passed, the only valid option is -r So in the command: rmeta mp4 -r mp4 is indexed at position [1] -r is indexed at position [2] because [2] == -r we now set recursive to True and continue on.

If -r was not passed recursive remains set to our default value False and we continue on.

if action_type == "mkv":
    mkv(recursive)
elif action_type =="mp4":
    mp4(recursive)
elif action_type =="all":
    mkv(recursive)
    mp4(recursive)
else:
    print("Usage: rmeta mkv|mp4|all append -r for recursive operations")
    sys.exit(1)

https://github.com/HarveyDevel/rmeta/blob/master/rmeta#L49

Now we start checking what [1] is set to and when we find a matching pattern we execute the function inside that if statement. In the prior example command [1] is set to mp4 so we skip to elif action_type =="mp4": and run the function mp4(recursive) which passes whatever value recursive currently holds in this case True

def mp4(recursive=False):
    if recursive:
        for mp4name in glob.glob('**/*.mp4', recursive=True):
            exec_mp4(mp4name)
            print(f"Title metadata of {mp4name} has been changed")
    else:
        for mp4name in glob.glob("*.mp4"):
            exec_mp4(mp4name)
            print(f"Title metadata of {mp4name} has been changed")

https://github.com/HarveyDevel/rmeta/blob/master/rmeta#L19

Because recursive == True we catch on the first if statement which will get files recursively from your current position matching the .mp4 pattern and use the exec_mp4(mp4name) function to perform the operation.

def exec_mp4(mp4name):
    mp4name_title=mp4_string(mp4name)
    subprocess.run(["kid3-cli", "-c", f"set title '{mp4name_title}'", mp4name])

https://github.com/HarveyDevel/rmeta/blob/master/rmeta#L15

An we finally sanitise the filename so certain characters will not break the script and use kid3-cli to set the title field metadata for the files found matching the pattern.

With no args

If you just run rmeta which is what you would be doing if you just double click it. There is no [1] arg so you drop down to else (a catch all for everything not already handled) which will simply print help and then exit with an error code.

else:
    print("Usage: rmeta mkv|mp4|all append -r for recursive operations")
    sys.exit(1)

https://github.com/HarveyDevel/rmeta/blob/master/rmeta#L56

A solution might be as simple as modifying that section to become:

else:
    recursive=True
    mp4(recursive)

Now having no args is valid, but operations are always recursive unless you edit the script again or maintain two different versions. Obviously do the same thing for mkv in the same modification.

skylinekiller commented 1 year ago

So here is a script where you just need to double click the .py and it will write all .mkv/.mp4 in the current and subdirectories.

import glob import subprocess import os

def mp4_string(title): name, name_extension = os.path.splitext(os.path.basename(title).replace("'", "\'")) return name

def mkv_string(title): name, name_extension = os.path.splitext(os.path.basename(title)) return name

def exec_mp4(mp4name): mp4name_title = mp4_string(mp4name) subprocess.run(["kid3-cli", "-c", f"set title '{mp4name_title}'", mp4name], shell=True)

def mp4(recursive=True): if recursive: for mp4name in glob.glob('*/.mp4', recursive=True): exec_mp4(mp4name) print(f"Title metadata of {mp4name} has been changed") else: for mp4name in glob.glob("*.mp4"): exec_mp4(mp4name) print(f"Title metadata of {mp4name} has been changed")

def exec_mkv(mkvname): mkvname_title = mkv_string(mkvname) subprocess.run(["mkvpropedit", "-e", "info", "-s", f"title={mkvname_title}", mkvname], shell=True)

def mkv(recursive=True): if recursive: for mkvname in glob.glob('*/.mkv', recursive=True): exec_mkv(mkvname) else: for mkvname in glob.glob("*.mkv"): exec_mkv(mkvname)

if name == "main": mkv(True) mp4(True)

input("Press Enter to exit...")