#1 2007-01-09 10:38

Ali3n5
Member
Registered: 2007-01-09
Posts: 4

Parse Date/Time from Filename -> File Created/Modified...

Hi Denis,

in the forum there is one or more topic(s) about the DV Date/Time within an AVI. The problem with DV-AVIs is the big size. At the moment I have more than 20 tapes (uncompressed AVI ~10-18 GB/tape). Store them uncompressed is I think not really sensible.

With the program AV-Cutty (http://www.avcutty.de/english/index.htm) I can save each szene as an extra AVI (uncompressed). With the tool SUPER (http://www.videohelp.com/tools?tool=SUPER_1) I can convert these AVIs in any other format, e.g. DivX.

AV-Cutty is at the moment not (but in the next version) able to write the DV date/time back to the speparate AVIs (szenes). But it can use this information within the filename. So I get files with the following syntax: Name_YYYY-MM-DD_HH-MM-SS.type.
Even if AV-Cutty or any other program can read an write the DV date/time to the file attributes, these informations are gone if I compress these AVIs. But also the compressed files have the date/time in the filename.

Now my request: May it be possible to parse the date and time from the filename and write this information back to the file properties?

Background information: I want to manage my video as my photos with the organizer of Photoshop Elements (PSE). PSE is able to import file properties (sorting issue) of items without EXIF-informations. If the date/time isn't set correcty these attributes are not sensible an must be set by hand for each AVI (PSE is able but only by hand).

Thanks in advance for every information or work.
Regards
Ali3n5

Last edited by Ali3n5 (2007-01-09 10:49)

Offline

#2 2007-01-10 02:59

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,379

Re: Parse Date/Time from Filename -> File Created/Modified...

Hi Ali3n5,

You will need 2 things: download latest development version ReNamerBeta.zip, and use the script below. Simply add the contents of the script to the PascalScript rule, add your files to ReNamer, and press Preview. Note: file dates will be changed exactly when you press preview, no need for rename operations, and do not add any other rules. New Name field will be used to display status, one of the 3 messages can appear there: "INVALID FORMAT", "FAILED TO SET FILE DATE", "SET TO: YYYY-MM-DD HH-MM-SS".

Tell me how it goes, ok?

{Set created and modified dates to the date found at the end of the filename}

// Converts text in format 'yyyy_mm_dd_hh_nn_ss' to data-time variable
// Note: underscore symbol can be any single character!  
function StringToDateTime(const Text: string; out ADateTime: TDateTime): Boolean;
var
  iYear, iMonth, iDay, iHour, iMin, iSec: Integer;
  Date, Time: TDateTime;
begin
  // extract date-time variables
  iYear  := StrToIntDef(Copy(Text, 1, 4), -1);
  iMonth := StrToIntDef(Copy(Text, 6, 2), -1);
  iDay   := StrToIntDef(Copy(Text, 9, 2), -1);
  iHour  := StrToIntDef(Copy(Text, 12, 2), -1);
  iMin   := StrToIntDef(Copy(Text, 15, 2), -1);
  iSec   := StrToIntDef(Copy(Text, 18, 2), -1);
  // check that all variables are correctly defined
  Result := (iYear >= 0) and (iMonth >= 0) and (iDay >= 0)
    and (iHour >= 0) and (iMin >= 0) and (iSec >= 0);
  if Result then
  begin
    // create resulting date-time variable
    Date := EncodeDate(iYear, iMonth, iDay);
    Time := EncodeTime(iHour, iMin, iSec, 0);
    ADateTime := Date + Time;
  end
end;

var
  DateTime: TDateTime;
  DatePart: WideString;

begin
  DatePart := WideExtractBaseName(FilePath);
  WideDelete(DatePart, 1, Length(DatePart)-19);
  if StringToDateTime(DatePart, DateTime) then
  begin
    if SetFileTimeModified(FilePath, DateTime) and
       SetFileTimeCreated(FilePath, DateTime) 
    then FileName := 'SET TO: '+FormatDateTime('yyyy-mm-dd hh-mm-ss', DateTime)
    else FileName := 'FAILED TO SET FILE DATE';
  end
  else FileName := 'INVALID FORMAT';
end.

Offline

#3 2007-01-10 07:54

Ali3n5
Member
Registered: 2007-01-09
Posts: 4

Re: Parse Date/Time from Filename -> File Created/Modified...

Hi Denis,

great. big_smile:D:D
After the test this evening I will inform you.

Ali3n5

Offline

#4 2007-01-10 11:40

fjord
Member
From: Denmark
Registered: 2006-08-25
Posts: 43

Re: Parse Date/Time from Filename -> File Created/Modified...

Hi Denis,

Is changing of filedates by SetFileTimeModified etc recoverable by UNDO in ReNamer?

I was thinking it would be nice to have a logical variable for "Preview/Commit Change" to postpone actually changing the dates until the Rename button is pressed. But since SetFileTimeModified returns a logical completion code, it is not so straightforward to implement what I'm thinking.

Is there a variable that indicates if the script is running in Preview or Rename mode?

Offline

#5 2007-01-10 15:00

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,379

Re: Parse Date/Time from Filename -> File Created/Modified...

Fjord, unfortunately both of your suggestions are impossible to implement. This is because "Rename" action DOES NOT execute the rules, it simply renames files from current name to whatever specified in the New Name field. It is only for the "Preview" action the rules get executed, in order to generate new names. That renders "Preview or Rename mode" impossible, and "UNDO for any manipulations within PascalScript" also impossible.

P.S. "Preview" button should really be called "Generate" hmm

Offline

#6 2007-01-11 12:43

Ali3n5
Member
Registered: 2007-01-09
Posts: 4

Re: Parse Date/Time from Filename -> File Created/Modified...

Hi Denis,

I get the following error: Pascal Script: [Error] (6:1): Identifier expected.

Regards
Ali3n5

Offline

#7 2007-01-11 13:31

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,379

Re: Parse Date/Time from Filename -> File Created/Modified...

I thinkg you have inserted the code above inside the "BEGIN .... END." statements, did you? The code should replace everything in the PascalScript text box, so clear the text box first, and then copy-and-paste the code above into that box AS IT IS in the post. It works for me!

Offline

#8 2007-01-11 13:52

Ali3n5
Member
Registered: 2007-01-09
Posts: 4

Re: Parse Date/Time from Filename -> File Created/Modified...

Hi Denis,

yes you are right. I inserted it between begin and end.
Now it works. Absolutly great. lol:lol::lol:

Many, many thanks.
Ali3n5

Offline

#9 2007-01-15 06:11

smw
Member
Registered: 2007-01-15
Posts: 3

Re: Parse Date/Time from Filename -> File Created/Modified...

I am trying to do something quite similar to this, but having some problems.  I have never coded in Pascal before (or Delphi, whatever the difference is), but I based my code off of the example above.

I am trying to rename avi files based off some date content in the first line of the file.  The date/time information always starts at position 325 for the avi files created by my digital camera.  I'm trying to parse that date/time info out and create a date/time object to reference for the name of the file.  However, I am running into 2 problems (one big one, and one small).  Here's my code (based off the previous code above):

{Set filename equal to the date found in the first line of the AVI file}
// Converts text in format 'mmm dd hh:nn:ss yyyy' to data-time variable

var
  dateText: string;
  iYear, iMonth, iDay, iHour, iMin, iSec: Integer;
  ADateTime, Date, Time: TDateTime;

begin
  // extract the date info from the first line (e.g. FEB 24 11:40:41 2005) starting at column 325
  dateText := Copy(FileReadLine(FileName, 1), 325, 20);

  // extract date-time variables
  iYear := StrToIntDef(Copy(dateText, 17, 4), -1);
  iDay  := StrToIntDef(Copy(dateText, 5, 2), -1);
  iHour := StrToIntDef(Copy(dateText, 8, 2), -1);
  iMin  := StrToIntDef(Copy(dateText, 11, 2), -1);
  iSec  := StrToIntDef(Copy(dateText, 14, 2), -1);

  //Determine the numerical month based off the three-letter abbreviation
  if Copy(dateText, 1, 3) = 'JAN' then iMonth := 1;
  if Copy(dateText, 1, 3) = 'FEB' then iMonth := 2;
  if Copy(dateText, 1, 3) = 'MAR' then iMonth := 3;
  if Copy(dateText, 1, 3) = 'APR' then iMonth := 4;
  if Copy(dateText, 1, 3) = 'MAY' then iMonth := 5;
  if Copy(dateText, 1, 3) = 'JUN' then iMonth := 6;
  if Copy(dateText, 1, 3) = 'JUL' then iMonth := 7;
  if Copy(dateText, 1, 3) = 'AUG' then iMonth := 8;
  if Copy(dateText, 1, 3) = 'SEP' then iMonth := 9;
  if Copy(dateText, 1, 3) = 'OCT' then iMonth := 10;
  if Copy(dateText, 1, 3) = 'NOV' then iMonth := 11;
  if Copy(dateText, 1, 3) = 'DEC' then iMonth := 12;

  // check that all variables are correctly defined
  Result := (iYear >= 0) and (iMonth >= 0) and (iDay >= 0)
    and (iHour >= 0) and (iMin >= 0) and (iSec >= 0);
  if Result then
  begin
    // create resulting date-time variable
    Date := EncodeDate(iYear, iMonth, iDay);
    Time := EncodeTime(iHour, iMin, iSec, 0);
    ADateTime := Date + Time;
  end

  // set filename to formatted date
  FileName := FormatDateTime('yyyy.mm.dd_hh.nn.ss (ddd, mmm dd, yyyy @ h.nn.ss am/pm)', ADateTime)+'.avi';
  
end.

My first problem has something to do with line 11 [dateText := Copy(FileReadLine(FileName, 1), 325, 20);].  That is the big problem...it does not work and I'm not sure what the problem is.  If I substitute the text it should be pulling, the rest of the code works, so there is something with this function (maybe it doesn't read an avi file??).

The second problem, which is small, is a problem compiling the code.  The Result section, to check that the integers are okay, gives me the following error:

Pascal Script [Error] (36,3): Unknown identifier 'Result'

I can comment that out and it's okay (hence the "small" problem), but I don't understand why it has an issue.  I pulled it straight from the original code.

Any help would be greatly appreciated.

And, by the way, AWESOME AWESOME program...very powerful, yet compact!  Love that it's stand-alone too.

smw

P.S.  I noticed that at the end of the original code, the date formatting is incorrect (i think, at least).  For the hour-min-sec, it says 'hh-mm-ss'...shouldn't that be 'hh-nn-ss', or else you are putting the month in there instead of the minute.

Offline

#10 2007-01-15 13:44

den4b
Administrator
From: den4b.com
Registered: 2006-04-06
Posts: 3,379

Re: Parse Date/Time from Filename -> File Created/Modified...

WOW! Some impressive post you wrote here, with loads of details! I wished everybody would explain them-selves that well! smile

Anyway, back to you problem. You done most of the job correctly, so congrats to you! FileReadLine(FileName, 1) didn't work because you used a wrong variable which specifies location of the file, it should be FileReadLine(FilePath, 1), because FileName is a dynamic NewName variable which is changed by rules and originated ONLY from the filename, e.g. "file.txt" - without path; while FilePath - holds the original path to the file. Unknown identifier 'Result' because you did not declare Result variable (as boolean), in the VAR section.

I put together (and cleanup a bit) the code that should work (see below). I defined the output format for datetime at the top of the script, so it'll be easier to change it. I removed the Result variable, because there was no need for it. And I've added some error handling for months and for overall result, it will set the name to "FAILED TO EXTRACT DATETIME" if it failed to read the date correctly. A bit later, I will also add another function to PascalScript rule, to read a fragment of the file, specified by the starting position and the length of the fragment, which will decrease the overhead from reading unnecessary data.

P.S. Well spoted for the "hh-mm-ss", but here is the extract from the date-time help file: mm -> Displays the month as a number with a leading zero (01-12). If the mm specifier immediately follows an h or hh specifier then minute is displayed. wink

const
  FORMAT = 'yyyy.mm.dd_hh.nn.ss (ddd, mmm dd, yyyy @ h.nn.ss am/pm)';

var
  dateText: string;
  iYear, iMonth, iDay, iHour, iMin, iSec: Integer;
  ADateTime, Date, Time: TDateTime;

begin
  // extract the date info from the first line (e.g. FEB 24 11:40:41 2005) starting at column 325
  dateText := Copy(FileReadLine(FilePath, 1), 325, 20);

  // extract date-time variables
  iYear := StrToIntDef(Copy(dateText, 17, 4), -1);
  iDay  := StrToIntDef(Copy(dateText, 5, 2), -1);
  iHour := StrToIntDef(Copy(dateText, 8, 2), -1);
  iMin  := StrToIntDef(Copy(dateText, 11, 2), -1);
  iSec  := StrToIntDef(Copy(dateText, 14, 2), -1);

  //Determine the numerical month based off the three-letter abbreviation
  if Copy(dateText, 1, 3) = 'JAN' then iMonth := 1
  else if Copy(dateText, 1, 3) = 'FEB' then iMonth := 2
  else if Copy(dateText, 1, 3) = 'MAR' then iMonth := 3
  else if Copy(dateText, 1, 3) = 'APR' then iMonth := 4
  else if Copy(dateText, 1, 3) = 'MAY' then iMonth := 5
  else if Copy(dateText, 1, 3) = 'JUN' then iMonth := 6
  else if Copy(dateText, 1, 3) = 'JUL' then iMonth := 7
  else if Copy(dateText, 1, 3) = 'AUG' then iMonth := 8
  else if Copy(dateText, 1, 3) = 'SEP' then iMonth := 9
  else if Copy(dateText, 1, 3) = 'OCT' then iMonth := 10
  else if Copy(dateText, 1, 3) = 'NOV' then iMonth := 11
  else if Copy(dateText, 1, 3) = 'DEC' then iMonth := 12
  else iMonth := -1;

  // check that all variables are correctly defined
  if (iYear >= 0) and (iMonth >= 0) and (iDay >= 0)
    and (iHour >= 0) and (iMin >= 0) and (iSec >= 0) then
  begin
    // create resulting date-time variable
    Date := EncodeDate(iYear, iMonth, iDay);
    Time := EncodeTime(iHour, iMin, iSec, 0);
    ADateTime := Date + Time;
    // set filename to formatted date
    FileName := FormatDateTime(FORMAT, ADateTime) + '.avi';
  end
  // something went wrong
  else FileName := 'FAILED TO EXTRACT DATETIME';
end.

Last edited by den4b (2007-01-15 13:47)

Offline

Board footer

Powered by FluxBB