1

Тема: VBS:Win XP ругается на CDate

Сделал себе скрипт для разбивки видеофайлов на куски


'сегментирование видео из командной строки с ffmpeg

input = "e:\Борджиа\"            'папка input
output= input&"segment\"        'папка segment
dlit="00:04:00"




Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = WScript.CreateObject("WScript.Shell")
If not objFSO.FolderExists(output) Then objFSO.CreateFolder output          'создаем output


RecursiveFolderScan input


'Создаём процедуру рекурсивного обхода каталога
Sub RecursiveFolderScan(FolderPath)
    'Получаем объектную модель текущего каталога
    Set Folder = objFSO.GetFolder(FolderPath)
 
    'Перебираем все файлы в текущем каталоге
    For Each File in Folder.Files
Name2 = objFSO.GetBaseName(File)
' проверяем на длительность
Set oFileDetailsReader = New cFileDetailsReader
With oFileDetailsReader
    .OpenFile File
        param = .GetDetail(27) 
s1="00:00:00"
i=1
Do While  CDate(param) > CDate(s1) 'на эту строку ругается

RetCode = WSHShell.Run ("""c:\ffmpeg\bin\ffmpeg.exe""  -i """ & File & """ -vcodec copy -map 0:0  -ss "& s1 &" -t "& dlit &" """&output&Name2&i&".avi",1,True) 'только видео


 ' складываем дату
s1 = DateDiff("s", 0, s1) + DateDiff("s", 0, dlit)
H = Int(s1/3600)     
M1 = s1   - (H * 3600)
M = Int(M1/60)       
S  = M1   - (M * 60)
s1 =  TimeSerial(H, M, S)
i=i+1

Loop
   End With
    Next
 

End Sub






Class cFileDetailsReader
    Private oFSO, oShellApp, oFolder3, oFolderItem
    
    Private Sub Class_Initialize()
        Set oFSO = CreateObject("Scripting.FileSystemObject")
        Set oShellApp = CreateObject("Shell.Application")
    End Sub
    
    Sub OpenFile(FilePath)
        With oFSO.GetFile(FilePath)
            Set oFolder3 = oShellApp.NameSpace(.ParentFolder.Path)
            Set oFolderItem = oFolder3.ParseName(.Name)
        End With
    End Sub
    
    Function GetDetail(Index)
        GetDetail = oFolder3.GetDetailsOf(oFolderItem,Index)
    End Function

    Function GetDetailName(Index)
        GetDetailName = oFolder3.GetDetailsOf(0,Index)
    End Function
End Class

под Win 7 SP1 работает отлично, а Win XP SP3  ругается на CDate.
Что ей не хватает?

2 (изменено: Flasher, 2015-08-13 07:45:32)

Re: VBS:Win XP ругается на CDate

Вот вроде показываешь, как надо, а бестолку. См. внимательно как у меня реализована рекурсия.
Зачем избыточный класс, если можно записать конструкцию внутри процедуры в 2 строки?
Зачем перебирать все файлы, если можно отфильтровать, чтобы ускорить процесс в разы?
Понятно, что CDate будет ругается на отсутсвующее поле при первом попавшемся негодном файле.
К тому же для XP индекс длительности 22, а не 27. Поэтому сперва нужно узнать версию системы в реестре.

3

Re: VBS:Win XP ругается на CDate

griha09, думаю к словам коллеги Flasher-а стоит прислушаться. Метод Filter гораздо эффективнее использовать чем фильтрацию перебором. Я так понял, Вы используете код из моего примера. Я на тот момент не имел полного представления об этом методе (Filter), поэтому не использовал его. Но сейчас считаю более рациональным переписать и использовать именно возможности Shell.Application.

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

4 (изменено: griha09, 2015-08-13 15:29:10)

Re: VBS:Win XP ругается на CDate

Flasher пишет:

Вот вроде показываешь, как надо, а бестолку. См. внимательно как у меня реализована рекурсия.
Зачем избыточный класс, если можно записать конструкцию внутри процедуры в 2 строки?
Зачем перебирать все файлы, если можно отфильтровать, чтобы ускорить процесс в разы?
Понятно, что CDate будет ругается на отсутсвующее поле при первом попавшемся негодном файле.
К тому же для XP индекс длительности 22, а не 27. Поэтому сперва нужно узнать версию системы в реестре.

Класс думал убрать, но потом лениво стало убирать.
Зачем отфильтровать если надо обработать все файлы?
Я даже предположить не мог что индекс длительности в Win 7 и Win XP отличается.




Xameleon пишет:

Я так понял, Вы используете код из моего примера.

Да.
Метод Filter я еще толком не понял.


Может кто знает как узнать длительность у MKV?
А то с помощью GetDetailsOf у AVI, MP4 и др. можно  узнать длительность, а у MKV нет.

5

Re: VBS:Win XP ругается на CDate

griha09 пишет:

Зачем отфильтровать если надо обработать все файлы?

Ситуации разные могут быть. Например, в папках есть другие файлы (торренты, временные файлы типа thumbs.db, descript.ion). А если есть аудио, то у них также есть длительность, но трогать их не нужно, то как? Далее яркий пример - MKV. Зачем его брать, если для него метод не годится? Для него разве доп. средства (пример - MediaInfoActiveX.dll из пакетов DLL without installer) использовать.

6

Re: VBS:Win XP ругается на CDate

так я до этого фильтрую, при копировании в эту папку.

7

Re: VBS:Win XP ругается на CDate

ДО чего - до этого? Никакой фильтрацией там не пахнет.

8

Re: VBS:Win XP ругается на CDate

griha09,

griha09 пишет:

А то с помощью GetDetailsOf у AVI, MP4 и др. можно  узнать длительность, а у MKV нет.

У меня нормально определяется длительность MKV. Возможно дело в установленных кодеках K-Lite Codec Pack, но не уверен.

http://forum.script-coding.com/misc.php?action=pun_attachment&item=1015&download=0

Передумал переделывать мир. Пашет и так, ну и ладно. Сделаю лучше свой !

9 (изменено: Flasher, 2015-08-14 18:05:42)

Re: VBS:Win XP ругается на CDate

Видимо, так и есть. Часть данных из контейнеров тащится благодаря встроенным по умолчанию в систему сплиттерам. Но в повседневность многих пользователей вошло задействование портабл-клиентов. И стоит или нет ради решения одной подобной задачи устанавливать свалки аля K-Lite, которые очень по-разному сказываются на проигрывании всяких видео, вопрос лично для меня бы не стоял. Можно, конечно, установить более сбалансированный пак, но и в этом случае не всё и всегда заканчивается положительным результатом, вплоть до того, что приходится заново устанавливать весь набор.

10

Re: VBS:Win XP ругается на CDate

Flasher пишет:

ДО чего - до этого? Никакой фильтрацией там не пахнет.

в процедуре разбивки видеофайлов на куски  фильтрацией не пахнет.
А перед ней есть процедура переноса видеофайлов с флешки, в ней есть фильтрация.




Exts = "*.3gp;*.asf;*.avi; *.mkv; *.mov;*.mp4;*.mpg;*.wmv;*.vob"
Exts2 = "*.av0;*.mp3"
flash="i:\tohdd\"
flash_out="i:\"
hdd="d:\Video\"
temp= hdd&"temp\"
output= hdd&"output\"        'папка output


Set Shell = CreateObject("Shell.Application")
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = WScript.CreateObject("WScript.Shell")


If not objFSO.FolderExists(hdd) Then objFSO.CreateFolder hdd          'создаем hdd чтоб не выдавало ошибку
If not objFSO.FolderExists(temp) Then objFSO.CreateFolder temp          'создаем temp
If not objFSO.FolderExists(output) Then objFSO.CreateFolder output          'создаем output


Do While true
If objFSO.FolderExists(flash) Then     
Perenos flash,temp, Exts                  ' переносим новые файлы с флешки в temp
Perenos output,flash_out,Exts2               ' переносим обработ файлы с винта на флешку
End If
  WScript.Sleep 300000
loop



Sub Perenos(Folder, Folder2, Exts)
  Set objFolder = Shell.NameSpace(Folder)
  Set objItems  = objFolder.Items
  objItems.Filter 192, Exts
  For Each File in objItems

 objFSO.MoveFile File.Path, Folder2            

  Next 
End Sub

Кстати и тут есть проблемка. По задумке скрипт вечно висит в памяти и при вставке флешки копирует определенные группы файлов, затем флешка безопасно излекается и  скрипт дальше висит в памяти. В принципе все работает, но после безопасного извлечения флешки (вручную,не скриптом) скрипт выдает ошибку (Win XP SP3)

11

Re: VBS:Win XP ругается на CDate

Xameleon пишет:

griha09,
У меня нормально определяется длительность MKV. Возможно дело в установленных кодеках K-Lite Codec Pack, но не уверен.

ну да, наверное , у меня такие окна свойств. А я то думал это по умолчанию в системе есть такая возможность  определяеть длительность. Значит буду пользовать MediaInfoActiveX.dll чтоб не зависеть от внешних факторов.
http://s016.radikal.ru/i337/1508/0b/21c9c43eb3cc.jpg

12

Re: VBS:Win XP ругается на CDate

griha09
Мда. А смысл что-то куда-либо переносить, если можно сразу обрабатывать исходные файлы?
Обращу также внимание, что стоило таки спросить про более грамотный перенос в надлежащем топике, ибо тут нет необходимости в цикле и FSO.
Разумеется, ошибка будет, а куда ей деться в таких условиях? Тут несомненно стоило прежде проверять диск по If FSO.DriveExists(I:) Then.
Я уже как-то писал, что лучше для таких вещей не vbs-скриптами пользоваться. Пусть лучше этим занимается программа, работающая на уровне ядра.

13

Re: VBS:Win XP ругается на CDate

Flasher пишет:

К тому же для XP индекс длительности 22, а не 27. Поэтому сперва нужно узнать версию системы в реестре.

Только не 22, а 21. Только что проверил.

14

Re: VBS:Win XP ругается на CDate

Тогда ситуация ещё хуже, чем я думал, ибо я вовсе не описался.

15

Re: VBS:Win XP ругается на CDate

вот переделал с MediaInfo, усе работает, правда mkv разрезает с ошибками, но это уже проблема ffmpeg

Раздражает появляющееся окно WshShell.Exec. Как его скрыть?


'сегментирование видео из командной строки в ffmpeg

ffmpeg="c:\ffmpeg\ffmpeg.exe"
MediaInfo="c:\MediaInfo_CL\MediaInfo.exe"
input = "d:\Video\"            'папка input
output= input&"segment\"        'папка segment
dlit="00:03:00"

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = WScript.CreateObject("WScript.Shell")
If not objFSO.FolderExists(output) Then objFSO.CreateFolder output          'создаем output

RecursiveFolderScan input

'Создаём процедуру рекурсивного обхода каталога
Sub RecursiveFolderScan(FolderPath)
    'Получаем объектную модель текущего каталога
    Set Folder = objFSO.GetFolder(FolderPath)
 
    'Перебираем все файлы в текущем каталоге
    For Each File in Folder.Files
Name2 = objFSO.GetBaseName(File)
' проверяем на длительность
Set WshExec = WshShell.Exec (MediaInfo&" "&"""--Inform=General;%Duration/String3%"" """ & File & """")
Set TextStream = WshExec.StdOut
    param = Left(TextStream.ReadLine(),8)

s1="00:00:00"
i=1
Do While  CDate(param) > CDate(s1)

RetCode = WSHShell.Run ("""" & ffmpeg & """  -i """ & File & """ -vcodec copy -acodec copy -ss "& s1 &" -t "& dlit &" """&output&Name2&i&".avi",0,True)

 ' складываем длительность
s1 = DateDiff("s", 0, s1) + DateDiff("s", 0, dlit)
H = Int(s1/3600)     
M1 = s1   - (H * 3600)
M = Int(M1/60)       
S  = M1   - (M * 60)
s1 =  TimeSerial(H, M, S)
i=i+1

Loop
    Next
 End Sub

16 (изменено: Flasher, 2016-03-15 05:24:02)

Re: VBS:Win XP ругается на CDate

Не надо ничего скрывать. Я же не просто так указал на компонент.
Пишем

With CreateObject("MediaInfo.ActiveX")
  handle = .MediaInfo_New()
  .MediaInfo_Open   handle, File
  .MediaInfo_Option handle, "Inform", "General;%Duration/String3%"
  Duration = .MediaInfo_Inform(handle, 0)
End With
    param = Left(Duration, 8)

вместо

MediaInfo="c:\MediaInfo_CL\MediaInfo.exe"
...
Set WshExec = WshShell.Exec (MediaInfo&" "&"""--Inform=General;%Duration/String3%"" """ & File & """")
Set TextStream = WshExec.StdOut
    param = Left(TextStream.ReadLine(),8)
+ Манифест, если надо:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity
  type="win32"
  name="MediaInfoActiveX.sxs"
  version="1.0.0.0" />
  <file name="MediaInfoActiveX.dll">
    <typelib
        tlbid="{0565A1AC-ED89-11DA-BA27-E0738ABD8F60}"
        version="1.0"
        helpdir="" />
    <comClass
        clsid="{0565A1A8-ED89-11DA-BA27-E0738ABD8F60}"
        threadingModel="Apartment"
        progid="MediaInfo.ActiveX" />
  </file>
    <comInterfaceExternalProxyStub
        name="ActiveX"
        iid="{0565A1A7-ED89-11DA-BA27-E0738ABD8F60}"
        proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
        tlbid="{0565A1AC-ED89-11DA-BA27-E0738ABD8F60}" />
</assembly>

17

Re: VBS:Win XP ругается на CDate

RecursiveFolderScan -  название не годится, тут нет никакой рекурсии. Да и вообще  процедура тут не нужна.
Do While  CDate(param) > CDate(s1) - можно смысл в необходимости подобного цикла объяснить? :\
И большая просьба уважить окружающих, не нужно пренебрегать общепонятной схематикой расстановки отступов.

18

Re: VBS:Win XP ругается на CDate

Flasher пишет:

Do While  CDate(param) > CDate(s1) - можно смысл в необходимости подобного цикла объяснить? :\

команда


"""" & ffmpeg & """  -i """ & File & """ -vcodec copy -acodec copy -ss "& s1 &" -t "& dlit &" """&output&Name2&i&".avi"

или в оригинале


ffmpeg -i input.avi -vcodec copy -acodec copy -ss 00:00:00 -t 00:05:00 segment.avi

-ss 00:00:00 - время откуда начинаем резать
-t 00:05:00 - длительность куска
Вот я отрезал, например, кусок с 0 до 5 минут, затем сложил 00:00:00+00:05:00, у меня стало -ss 00:05:00, затем отрезал кусок с 5 до 10 минут итд. до конца видео. Поэтому и нужен цикл до конца видео.

Flasher пишет:

И большая просьба уважить окружающих, не нужно пренебрегать общепонятной схематикой расстановки отступов.

Это о чем?

19

Re: VBS:Win XP ругается на CDate

griha09 пишет:

Вот я отрезал, например, кусок с 0 до 5 минут, затем сложил 00:00:00+00:05:00, у меня стало -ss 00:05:00, затем отрезал кусок с 5 до 10 минут итд. до конца видео. Поэтому и нужен цикл до конца видео.

Я пишу про подобный цикл, а не сам цикл. Ведь правильней использовать For i = 0 to Minute(param).

griha09 пишет:

Это о чем?

О коде, разумеется.

20 (изменено: griha09, 2015-08-15 19:43:55)

Re: VBS:Win XP ругается на CDate

Flasher пишет:

Не надо ничего скрывать. Я же не просто так указал на компонент.
Пишем

With CreateObject("MediaInfo.ActiveX")
  handle = .MediaInfo_New()
  .MediaInfo_Open   handle, File
  .MediaInfo_Option handle, "Inform", "General;%Duration/String3%"
  Duration = .MediaInfo_Inform(handle, 0)
End With
    param = Left(Duration, 8)

Я, к сожалению, ни разу не программист, поэтому эта подсказка мне не помогла.
Переделал код в скрипте
скачал MediaInfo_DLL_0.7.76_Windows_i386_WithoutInstaller.7z распаковал, нашел MediaInfoActiveX.dll, в той же папке запустил MediaInfoActiveX_Install.bat
в ОС появились
c:\Windows\System32\MediaInfo.dll
c:\Windows\System32\MediaInfoActiveX.dll
запустил скрипт, появилась ошибка
http://i72.fastpic.ru/big/2015/0815/a0/7f30ce8cac3ac2057301d782cea23ca0.jpg
на эту строку


With CreateObject("MediaInfo.ActiveX")

Для проверки ввел
regsvr32 c:\Windows\System32\MediaInfoActiveX.dll
получил ошибку
http://i70.fastpic.ru/big/2015/0815/4a/9d84b1a55246f40d89f5db6e72a19c4a.jpg

Размер MediaInfoActiveX.dll - 22016 байт. Чето маловато, наверное.

Что делать с манифестом?

21

Re: VBS:Win XP ругается на CDate

Flasher пишет:

Я пишу про подобный цикл, а не сам цикл. Ведь правильней использовать For i = 0 to Minute(param).

Че-то недогадался, да и Do While  CDate(param) > CDate(s1) отлично работает.


Flasher пишет:
griha09 пишет:

Это о чем?

О коде, разумеется.

в смысле что за "общепонятной схематикой расстановки отступов"

22

Re: VBS:Win XP ругается на CDate

запустил скрипт, появилась ошибка

Текст сообщения забирается по Ctrl+C без всяких скриншотов.
Ошибка могла бы появится в случае отсутствия регистрации. Случайно, Uninstall не запускался? Регистрация была на x32 системе?

griha09 пишет:

Размер MediaInfoActiveX.dll - 22016 байт. Чето маловато, наверное.

Да ну? dynwrapx.dll вдвое меньше.

griha09 пишет:

Что делать с манифестом?

Именуется MediaInfoActiveX.sxs.manifest. Кладётся рядом с MediaInfo.dll, компонентом, wscript.exe и

+ wscript.exe.manifest

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
  type="win32"
  name="wscript.exe"
  version="1.0.0.0" />

  <dependency>
          <dependentAssembly>
              <assemblyIdentity
                  type="win32"
                  name="MediaInfoActiveX.sxs"
                  version="1.0.0.0" />
          </dependentAssembly>
  </dependency>

</assembly>

запускается: "путь к данному wscript.exe" "путь к скрипту".
Получается переносной вариант (кнопка в ФМ, ярлык и т.п.).

griha09 пишет:

в смысле что за "общепонятной схематикой расстановки отступов"

Читаем.

23

Re: VBS:Win XP ругается на CDate

Результаты по MediaInfoActiveX.dll

В Win XP MediaInfoActiveX.dll зарегистрировался успешно

DllRegisterServer в c:\WINDOWS\system32\MediaInfoActiveX.dll завершено успешно.

но все равно выдает ошибку

---------------------------
Windows Script Host
---------------------------
Сценарий:    c:\MediaInfoActiveX.vbs
Строка:    15
Символ:    3
Ошибка:    Несоответствие типа: 'MediaInfo_Open'
Код:    800A000D
Источник:     Ошибка выполнения Microsoft VBScript

---------------------------
ОК   
---------------------------

В Win7 MediaInfoActiveX.dll просто не хочет зарегистрироватся

[Window Title]
RegSvr32
[Content]
Не удалось загрузить модуль "c:\Windows\System32\MediaInfoActiveX.dll".

Проверьте, что двоичный файл хранится на указанном пути или запустите отладку, чтобы диагностировать проблемы с этим двоичным файлом или зависимыми DLL-файлами.
Не найден указанный модуль.
[ОК]

потому и выдает ошибку

---------------------------
Windows Script Host
---------------------------
Сценарий:    C:\MediaInfoActiveX.vbs
Строка:    13
Символ:    1
Ошибка:    Невозможно создание объекта контейнером ActiveX: 'MediaInfo.ActiveX'
Код:    800A01AD
Источник:     Ошибка выполнения Microsoft VBScript

---------------------------
ОК   
---------------------------

ну ладно не надо Win7, что WinXP не нравится в 'MediaInfo_Open'?

вот скрипт MediaInfoActiveX.vbs


input = "d:\Video\"            'папка input

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set WSHShell = WScript.CreateObject("WScript.Shell")


    'Получаем объектную модель текущего каталога
    Set Folder = objFSO.GetFolder(input)
 
    'Перебираем все файлы в текущем каталоге
    For Each File in Folder.Files

With CreateObject("MediaInfo.ActiveX")
  handle = .MediaInfo_New()
  .MediaInfo_Open   handle, File
  .MediaInfo_Option handle, "Inform", "General;%Duration/String3%"
  Duration = .MediaInfo_Inform(handle, 0)
End With
    param = Left(Duration, 8)

MsgBox Str
    Next

Set WSHShell = Nothing

24 (изменено: Flasher, 2015-08-18 11:29:23)

Re: VBS:Win XP ругается на CDate

Как-то уже глаза мылит от этой 'порнографии'. Оформил:

ffmpeg   = """C:\ffmpeg\ffmpeg.exe"""
Input    = "D:\Video\"         ' папка input
Output   = Input & "segment\"  ' папка segment
Interval = CDate("00:03:00")

Set FSO = CreateObject("Scripting.FileSystemObject")
Dim WSH : Set WSH = WScript.CreateObject("WScript.Shell")
If Not FSO.FolderExists(Output) Then FSO.CreateFolder Output

For Each File in FSO.GetFolder(Input).Files
  Name = FSO.GetBaseName(File)
  With CreateObject("MediaInfo.ActiveX")
    Handle = .MediaInfo_New()
    .MediaInfo_Open   Handle, CStr(File)
    .MediaInfo_Option Handle, "Inform", "General;%Duration/String3%"
    Duration = Left(.MediaInfo_Inform(Handle, 0), 8)
  End With
  S1 = "00:00:00"
  For i = 1 To Int(CDate(Duration)/Interval)
    WSH.Run ffmpeg & " -i """ & File & """ -vcodec copy -acodec copy -ss " _
    & S1 & " -t " & Interval & " """ & Output & Name & i & ".avi""", 0, True
    S1 = CDate(S1) + Interval
  Next
Next

На 7-ке советую с манифестом попробовать.

25

Re: VBS:Win XP ругается на CDate

Спасибо!!!

26 (изменено: Flasher, 2015-08-18 11:31:00)

Re: VBS:Win XP ругается на CDate

griha09 пишет:

Спасибо!!!

Пож-та, сейчас ещё мелкие правки внёс с Run.