You are not logged in.
I have a show on my computer that's 50 episodes long. I had to get the subtitle files separately. I understand this could probably be done in the same amount of time by going to UserInput, and pasting the video file names in there, but I'd greatly appreciate furthering my programming knowledge in general.
This the name of the video files, which was then copied to a text file:
L:\Anime\00 Anime_Show\renamer sample\[AnimeShow][20][BDRIP][960x720][X264-10bit_AAC].mp4
L:\Anime\00 Anime_Show\renamer sample\[AnimeShow][21][BDRIP][960x720][X264-10bit_AAC].mp4
L:\Anime\00 Anime_Show\renamer sample\[AnimeShow][22][BDRIP][960x720][X264-10bit_AAC].mp4
L:\Anime\00 Anime_Show\renamer sample\[AnimeShow][23][BDRIP][960x720][X264-10bit_AAC].mp4
L:\Anime\00 Anime_Show\renamer sample\[AnimeShow][24][BDRIP][960x720][X264-10bit_AAC].mp4
L:\Anime\00 Anime_Show\renamer sample\[AnimeShow][25][BDRIP][960x720][X264-10bit_AAC].mp4
To obtain the video file name in Microsoft Windows 7:
Select all the video files
Hold the Shift key
Right click and select 'Copy as Path'.
{Unnecessary} Go into Microsoft Excel, to sort the names in order. Note that excel drops the "quotation" marks. You may optionally run the following in the column next to it: =MID(A1, FIND("[AnimeS", A1), FIND(".mp4", A1)- FIND("[AnimeS", A1)). I didn't use this shortened version in the text file though
Paste the values from Excel into a basic text editor like notepad
File names of subtitle files dragged into ReNamer:
Anime_Show_20.ssa
Anime_Show_21.ssa
Anime_Show_22.ssa
Anime_Show_23.ssa
Anime_Show_24.ssa
Anime_Show_25.ssa
This is the algorithm I came up with thus far in Lazarus, an IDE for FreePascal:
{$mode objfpc}
uses classes;
var
VideoNames: TStringlist; {TStringlist is similar to a Java ArrayList}
i: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
videoFileName: String;
wsExample: WideString;
begin
VideoNames := TStringList.Create;
try
VideoNames.LoadFromFile('L:\Anime\00 Anime_Show\renamer sample\filenames.txt');
WriteLn('Total VideoNames: ', VideoNames.Count); {debugging purpose}
{It seems ReNamer, will run this entire code for each of the
dragged files individually, and they are presented by the variable
'FileName' by default}
for i := 0 to VideoNames.Count-1 do
begin
currentVideoEpisode := copy(VideoNames[i], 51, 2);
{videoFileName := copy(VideoNames[i], 39, 57);}
videoFileName := copy(VideoNames[i],
Pos('[Ani',VideoNames[i]),
Pos('.mp4', VideoNames[i])- Pos('[Ani',VideoNames[i]));
writeln(currentVideoEpisode, ' ', videoFileName); {debugging}
{FileName is predefined in rename as a WideString type}
{currentSubtitleEpisode := copy(FileName, 12, 2)}
{copy is equivalent to a Java Substring function}
{If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName:= videoFileName;}
end;
readln {debugging}
finally
VideoNames.Free;
en
The algorithm is executable and does include commented pseudo code, to better explain what I'm trying to do.
I was hoping, if someone could please complete this 'Custom' rule for the program for me and anyone else that may wish to use it. If it is too time consuming, I don't mind putting some effort in the algorithm.
The following results in a compile error:
{$mode objfpc}
uses classes;
var
VideoNames: TStringlist; {TStringlist is similar to a Java ArrayList}
i: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
videoFileName: String;
begin
VideoNames := TStringList.Create;
try
VideoNames.LoadFromFile('L:\Anime\00 Anime_Show\renamer sample\filenames.txt');
for i := 0 to VideoNames.Count-1 do
begin
currentVideoEpisode := copy(VideoNames[i], 51, 2);
currentSubtitleEpisode := copy(FileName, 12, 2)};
{videoFileName := copy(VideoNames[i], 39, 57);}
videoFileName := copy(VideoNames[i],
Pos('[Ani',VideoNames[i]),
Pos('.mp4', VideoNames[i]) - Pos('[Ani',VideoNames[i]));
{copy is equivalent to a Java Substring function}
If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName := videoFileName;
end;
finally
VideoNames.Free;
end;
end.
PS
[list=1] only allows number 1
Last edited by lanceru (2017-01-26 06:13)
Offline
Lazarus and ReNamer's Pascal Script use the same Pascal syntax, but the list of available types, classes and functions is very different.
The documentation for ReNamer's Pascal Script is available here:
http://www.den4b.com/wiki/ReNamer:Pasca … :Functions
Here is an example script which demonstrates how to port your logic to ReNamer's Pascal Script:
const
SourceFile = 'filenames.txt';
var
VideoFiles: TAnsiStringArray;
I: Integer;
begin
VideoFiles := FileReadLines(SourceFile);
for I := 0 to Length(VideoFiles) - 1 do
begin
// ...
// if found matching video file then
// ...
FileName := VideoFiles[I];
end;
end.
Alternatively, instead of using a manually created lookup list of filenames, you could scan the subtitle's directory for MP4 files using WideScanDirForFiles function.
Offline
Thanks for responding, I was able to gain a great leap with the following:
const
SourceFile = 'L:\Anime\00 Anime_Show\renamer sample\filenames.txt';
var
VideoFiles: TAnsiStringArray;
I: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
videoFileName: String;
begin
VideoFiles := FileReadLines(SourceFile);
for I := 0 to Length(VideoFiles) - 1 do
begin
currentVideoEpisode := copy(VideoFiles[i], 51, 2);
currentSubtitleEpisode := copy(FileName, 12, 2)};
{videoFileName := copy(VideoNames[i], 39, 57);}
videoFileName := copy(VideoFiles[i],
Pos('[Ani',VideoFiles[i]),
Pos('.mp4', VideoFiles[i]) - Pos('[Ani',VideoFiles[i]));
If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName := videoFileName;
end;
end.
When I click compile, the error states that there's a syntax error at line 13 and an unexpected end to the file at that same line:
Line 13: currentSubtitleEpisode := copy(FileName, 12, 2)};
I would definitely like to use the function WideScanDirForFiles, once I get the current algorithm up an running.
I came up with the following: WideScanDirForFiles('L:\Anime\00 Anime_Show\renamer sample\', '...\renamer sample\', false, false, false, '*.mp4')
From there I'm guessing I can retrieve the value of the 2nd argument for the StringArray.
+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| procedure | You can get a list of the files inside a folder. |
+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
| WideScanDirForFiles(const Dir: WideString; var Files: TStringsArray; | Dir: The folder you want to scan. |
| | Files: Where the list of files is going to be saved. |
| | Recursive: Do you want to scan the subfolders? |
| const Recursive, IncludeHidden, IncludeSystem: Boolean; const Mask: WideString); | IncludeHidden: Do you want to list the hidden files? |
| | IncludeSystem: Do you want to list the system files? |
| | Mask: You can list everything ('*'), or only the files that contain some string (example: '*.txt'). |
+----------------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------+
Last edited by lanceru (2017-01-26 18:41)
Offline
When I click compile, the error states that there's a syntax error at line 13 and an unexpected end to the file at that same line:
Line 13: currentSubtitleEpisode := copy(FileName, 12, 2)};
Read the *WIKI* for HELP + MANUAL + Tips&Tricks.
If ReNamer had helped you, please *DONATE* to Denis or buy a PRO license. (Read *Lite vs Pro*)
Offline
Thank you.
const
SourceFile = 'L:\Anime\00 Anime_Show\renamer sample\filenames.txt';
var
VideoFiles: TAnsiStringArray;
I, videoEpPOS, subEpPOS: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
videoFileName, subExtension: String;
begin
VideoFiles := FileReadLines(SourceFile);
subExtension := WideCopyRight(FileName, 1, 4);
videoEpPOS := Pos('[20]', VideoFiles[0]) + 1; {must manually specify ep# of file in 0th index}
subEpPOS := Pos('_01', 'Anime_Show_01') + 1;
for I := 0 to Length(VideoFiles) - 1 do
begin
currentVideoEpisode := copy(VideoFiles[i], videoEpPOS, 2);
currentSubtitleEpisode := copy(FileName, subEpPOS, 2);
videoFileName := copy(VideoFiles[i],
Pos('[Ani',VideoFiles[i]),
Pos('.mp4', VideoFiles[i]) - Pos('[Ani',VideoFiles[i]));
If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName := videoFileName + subExtension;
end;
end.
When executing the following statement:
FileName := videoFileName;
Is there a built in function in ReNamer to leave the file extension of FileName alone?
Otherwise I'd have to store RightStr(FileName, 4)/WideCopyRight(FileName, 1, 4) as variable and then append it to the renamed FileName.
Additionally I'm attempting the WideScanDirForFiles method, instead of importing a text file. The last argument, '*.mp4', seems cause a type mismatch error (i isolated it to its own line by pressing return after the comma).
var
VideoFiles: TAnsiStringArray;
I, videoEpPOS, subEpPOS: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
BasePath, videoFileName, subExtension: String;
begin
BasePath := WideExtractFilePath(FilePath);
WideScanDirForFiles(BasePath, VideoFiles, False, False, False, '*.mp4');
subExtension := (RightStr(FileName, 1, 4));
videoEpPOS := Pos('[20]', VideoFiles[0]) + 1; {must manually specify ep# of file in 0th index}
subEpPOS := Pos('_01', 'Anime_Show_01') + 1;
for I := 0 to Length(VideoFiles) - 1 do
begin
currentVideoEpisode := copy(VideoFiles[i], videoEpPOS, 2);
currentSubtitleEpisode := copy(FileName, subEpPOS, 2);
videoFileName := WideExtractBaseName(VideoFiles[i]);
If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName := videoFileName + subExtension;
end;
end.
Last edited by lanceru (2017-01-27 01:19)
Offline
>>> Is there a built in function in ReNamer to leave the file extension of FileName alone?
var
BaseName, Extension, pattern : WideString;
begin
////set own basic variable:
BaseName := WideExtractBaseName(FileName);
Extension := WideExtractFileExt(FileName);
>>> WideScanDirForFiles method,, seems cause a type mismatch error
Do you know what 'Wide' means?
I don't know out of my head if 'Unicode' is the right term here, but 'Wide' works like that.
And so that doesn't fit with "VideoFiles: TAnsiStringArray;" declaration (ANSI <> Unicode)
Try with "VideoFiles: TWideStringArray;" Array of WideString
Ah, of course, I found the answer: http://www.den4b.com/wiki/ReNamer:Pasca … ring_types
Read the *WIKI* for HELP + MANUAL + Tips&Tricks.
If ReNamer had helped you, please *DONATE* to Denis or buy a PRO license. (Read *Lite vs Pro*)
Offline
I had no luck in changing the array type to TWideStringArray, or changing the variables BasePath, videoFileName to WideString. I do aplogize for saying '*.mp4' was the culprit. I pressed the return key before the 2nd argument, and it turns out VideoFiles at line 9, is responsible causing the mismatch error.
var
VideoFiles: TWideStringArray;
I, videoEpPOS, subEpPOS: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
BasePath, videoFileName: WideString;
begin
BasePath := WideExtractFilePath(FilePath);
WideScanDirForFiles(BasePath,
VideoFiles, False, False, False, '*.mp4');
{subExtension := RightStr(FileName, 1, 4)); }
videoEpPOS := Pos('[01]', VideoFiles[0]) + 1; {must specify ep# at 0th ndx}
subEpPOS := Pos('_01', 'Anime_Show_01') + 1;
for I := 0 to Length(VideoFiles) - 1 do
begin
currentVideoEpisode := copy(VideoFiles[i], videoEpPOS, 2);
currentSubtitleEpisode := copy(FileName, subEpPOS, 2);
videoFileName := WideExtractBaseName(VideoFiles[i]);
If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName := videoFileName + WideExtractFileExt(FileName);
end;
end.
Offline
I had no luck in changing the array type to TWideStringArray,
OK, I did take a closer look onto the wiki:
procedure WideScanDirForFiles(
const Dir: WideString;
var Files: TStringsArray;
const Recursive, IncludeHidden, IncludeSystem: Boolean;
const Mask: WideString);
Looks like that "var Files" needs an "TStringsArray"? (not Ansi and not Wide ?)
Can you try that?
var
VideoFiles: TStringArray;
begin
WideScanDirForFiles(BasePath, VideoFiles, False, False, False, '*.mp4');
" BasePath, videoFileName: WideString; " should be ok anyway.
Read the *WIKI* for HELP + MANUAL + Tips&Tricks.
If ReNamer had helped you, please *DONATE* to Denis or buy a PRO license. (Read *Lite vs Pro*)
Offline
Thank you again that did the trick.
var
VideoFiles: TStringsArray;
I, videoEpPOS, subEpPOS: Integer;
currentVideoEpisode, currentSubtitleEpisode: String;
BasePath, videoFileName, Extension: WideString;
begin
BasePath := WideExtractFilePath(FilePath);
WideScanDirForFiles(BasePath, VideoFiles, False, False, False, '*.mp4');
Extension := WideExtractFileExt(FileName);{(RightStr(FileName, 1, 4)); }
videoEpPOS := Pos('[01]', VideoFiles[0]) + 1; {must specify ep# at 0th ndx}
subEpPOS := Pos('_01', 'Anime_Show_01') + 1;
for I := 0 to Length(VideoFiles) - 1 do
begin
currentVideoEpisode := copy(VideoFiles[i], videoEpPOS, 2);
currentSubtitleEpisode := copy(FileName, subEpPOS, 2);
videoFileName := WideExtractBaseName(VideoFiles[i]);
If (currentSubtitleEpisode = currentVideoEpisode) Then
FileName := videoFileName + Extension;
end;
end.
If anyone wishes to use or make this code more scalable, feel free to do so. I'll try to make determining videoEpPos and subEpPos (episode positions) better
Last edited by lanceru (2017-01-27 18:18)
Offline
Looks like that "var Files" needs an "TStringsArray"? (not Ansi and not Wide ?)
TStringsArray is a deprecated alias for TWideStringArray:
ReNamer:Pascal_Script:Types#Extra_types
It will soon be replaced by TWideStringArray in function signatures and documentation, to avoid confusion. TStringsArray type declaration will remain for backwards compatibility.
Offline