Как из wmv-файла вытащить длительность видео-фрагмента?

Тема в разделе "WASM.BEGINNERS", создана пользователем Mikl___, 15 май 2017.

  1. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.710
    Как из wmv-файла вытащить длительность видео-фрагмента? Или, как вариант, как при помощи wmplayer узнать продолжительность проигрывания видео-фрагмента? Или где можно посмотреть документацию по структуре wmv-файлов?
     
  2. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    861
    Можно через GetDetailsOf;
    Можно через DirectShow;
    Можно через mciSendCommand/mciSendString.
     
  3. Thetrik

    Thetrik UA6527P

    Публикаций:
    0
    Регистрация:
    25 июл 2011
    Сообщения:
    861
    Сделал небольшой пример с использованием DirectShow, нужный файл передается в параметре командной строки:
    Код (ASM):
    1. format PE console
    2.  
    3. entry startup
    4.  
    5. include 'win32ax.inc''.idata' import data readable
    6.  
    7.   library kernel,'KERNEL32.DLL',\
    8.           ole,'OLE32.DLL', \
    9.           msvcrt, 'msvcrt.dll', \
    10.           shell, 'shell32.dll'
    11.  
    12.   import kernel,\
    13.          ExitProcess,'ExitProcess', \
    14.          GetCommandLine, 'GetCommandLineW'
    15.  
    16.  
    17.   import ole,\
    18.          CoInitialize,'CoInitialize',\
    19.          CoCreateInstance,'CoCreateInstance'
    20.  
    21.   import msvcrt, \
    22.          printf, 'printf'
    23.  
    24.   import shell, \
    25.          CommandLineToArgvW, 'CommandLineToArgvW'
    26.  
    27. section '.text' code readable executable
    28.  
    29. IID_IGraphBuilder GUID 56a868a9-0ad4-11ce-b03a-0020af0ba770
    30. IID_IMediaSeeking GUID 36b73880-c2c8-11cf-8b46-00805f6cef60
    31. CLSID_FilterGraph GUID E436EBB3-524F-11CE-9F53-0020AF0BA770
    32. const_100ns dq 10000000.0
    33.  
    34. proc startup
    35.  
    36.     locals
    37.             graphBuilder    IGraphBuilder
    38.             pSource         IBaseFilter
    39.             pPin            IPin
    40.             mediaSeeking    IMediaSeeking
    41.             sSource         du "Source", 0
    42.             sOutput         du "Output", 0
    43.             pFileName       dd ?
    44.             lDuration       dq 0
    45.             argc            dd 0
    46.     endl
    47.  
    48.     finit
    49.  
    50.     invoke  CommandLineToArgvW, <invoke GetCommandLine>, addr argc
    51.  
    52.     .if ([argc] <> 2)
    53.         cinvoke printf, "Usage: app.exe path_to_media"
    54.     .else
    55.  
    56.         lea eax, [eax + 4]
    57.         mov eax, [eax]
    58.         mov [pFileName], eax
    59.  
    60.         invoke  CoInitialize, NULL
    61.         invoke  CoCreateInstance, CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, IID_IGraphBuilder, addr graphBuilder
    62.  
    63.         .if (signed eax >= 0)
    64.  
    65.             cominvk graphBuilder, AddSourceFilter, [pFileName], addr sSource, addr pSource
    66.  
    67.             .if (signed eax >= 0)
    68.  
    69.                 cominvk pSource, FindPin, addr sOutput, addr pPin
    70.  
    71.                 .if (signed eax >= 0)
    72.  
    73.                     cominvk graphBuilder, Render, [pPin]
    74.  
    75.                     .if (signed eax >= 0)
    76.  
    77.                         cominvk graphBuilder, QueryInterface, IID_IMediaSeeking, addr mediaSeeking
    78.  
    79.                         .if (signed eax >= 0)
    80.  
    81.                             cominvk mediaSeeking, GetDuration, addr lDuration
    82.  
    83.                             .if (signed eax >= 0)
    84.  
    85.                                 fild [lDuration]
    86.                                 fdiv [const_100ns]
    87.                                 fstp [lDuration]
    88.  
    89.                                 cinvoke printf, "Duration: %f sec.", double [lDuration]
    90.  
    91.                             .else
    92.                                 cinvoke printf, "IMediaSeeking::GetDuration failed 0x%x", eax
    93.                             .endif
    94.  
    95.                             cominvk mediaSeeking, Release
    96.  
    97.                         .else
    98.                             cinvoke printf, "IGraphBuilder::QueryInterface failed 0x%x", eax
    99.                         .endif
    100.  
    101.                     .else
    102.                         cinvoke printf, "IGraphBuilder::Render failed 0x%x", eax
    103.                     .endif
    104.  
    105.                     cominvk pPin, Release
    106.  
    107.                 .else
    108.                     cinvoke printf, "IBaseFilter::FindPin failed 0x%x", eax
    109.                 .endif
    110.  
    111.                 cominvk pSource, Release
    112.  
    113.             .else
    114.                 cinvoke printf, "IGraphBuilder::AddSourceFilter failed 0x%x", eax
    115.             .endif
    116.  
    117.             cominvk graphBuilder, Release
    118.  
    119.         .else
    120.             cinvoke printf, "CoCreateInstance failed 0x%x", eax
    121.         .endif
    122.     .endif
    123.  
    124.     invoke ExitProcess, 0
    125.  
    126.     ret
    127.  
    128. endp
    Для перевода в часы/минуты/секунды можно использовать к примеру StrFromTimeInterval.
     
    ol. и Коцит нравится это.
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.710
    Thetrik,
    огромное спасибо за помощь :good3:
     
  5. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.710
    в wmv-файле на 66h от начала в qword длительность файла в 100 nSec, то есть для перевода в mSec это значение нужно разделить на 10000
    Код (ASM):
    1. local lpcbData:dword
    2. local hFile:qword
    3. local szBuff[100h]:byte
    4.               . . . .
    5. ;get the length of playing a wmv-file
    6.              mov qword ptr [rsp+30h],0 ;hTemplateFile
    7.              mov qword ptr [rsp+28h],FILE_ATTRIBUTE_ARCHIVE ;dwFlagsAndAttributes
    8.              mov qword ptr [rsp+20h],OPEN_EXISTING ;dwCreationDisposition
    9.              lea rcx,FileName    ;lpFileName
    10.              invoke CreateFile,,GENERIC_READ,\    ;dwDesiredAccess
    11.              FILE_SHARE_READ or FILE_SHARE_WRITE,\;dwShareMode
    12.              0 ;lpSecurityAttributes
    13.              mov hFile,rax;handle to file
    14.              mov qword ptr [rsp+20h],0
    15.              lea r9,lpcbData
    16.              lea rdx,szBuff
    17.              invoke ReadFile,eax,,100h
    18.              invoke CloseHandle,hFile
    19.              mov rax,qword ptr szBuff[66h];duration in 100 nSec
    20. ;Duration in 100 nSec-units is divided by 10000 and get in duration in 1 mSec-units
    21.              mov edx,3518437209;"magic number"
    22.              mul edx
    23.              shr edx,13
    24.              mov duration,rdx;in mSec
    реализация здесь