IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 Delphi Discussion :

[D7] Durée d'une vidéo au format MP4


Sujet :

Delphi

  1. #1
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut [D7] Durée d'une vidéo au format MP4
    Bonjour,

    j'aimerais connaitre la durée de la vidéo d'u fichier MP4. J'ai trouvé ceci sur le net :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    //    Uses     mmsystem ...
    function GetVideoTime(Fichier: string): string;
    begin
      Result := '';
      mciSendString(PChar('close ' + Fichier), 0, 0, 0);
      mciSendString(PChar('open ' + Fichier + ' type MPEGVideo alias fichier'), 0, 0, 0);
      mciSendString(PChar('set ' + Fichier + ' time format ms'), 0, 0, 0);
      mciSendString(PChar('status' + Fichier + ' length'), PChar(Result), 128, 0);
      mciSendString(PChar('close ' + Fichier), 0, 0, 0);
    end ;
    Mais ça ne fonctionne pas (EAcessviolation dans NDParser.ax). Quelqu'un l'a t il déjà fait ?

    Merci
    A+
    Charly

  2. #2
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    non...mais si j'étais toi je chercherais plutôt à connaître l'entête des fichiers MP4 qui contient probablement l'info

    un programmeur C++ s'est fait la même réflexion
    https://geekthis.net/post/c-get-mp4-duration/
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  3. #3
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  4. #4
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut
    Merci à tout les deux,

    @Paul Toth : je ne comprends pas le code C++ et ne sais donc pas le traduire en Delphi.

    @Galet : j'avais déjà vu ton premier lien. Pour la norme, ça à l'air compliqué, je n'ai pas trouvé la longueur de la vidéo (Duration ?)

    Bref, ça n'a pas l'air simple.

    je vais chercher dans 2 directions :
    - essayer de comprendre le code C++
    - regarder la signature et la structure des MP4 pour les lire.

    A+
    Charly

  5. #5
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 420
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 420
    Points : 1 325
    Points
    1 325
    Par défaut
    Bonjour à toutes et à tous,

    @ Charly910, avec un TLabel et un Timer, je récupère la durée d'un fichier .mp4.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    procedure TFLecteur.Timer1Timer(Sender: TObject);
    var
      Duration: double;
      Position: double;
     
    begin
     
    LabelPisteEnCours.Caption:= ''+mp1.currentMedia.durationString+'';
     
    Ecouler.caption := ''+mp1.Controls.currentPositionString+'';
     
    end;
    A essayer dans ton code !

    @+,

    cincap

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 447
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 447
    Points : 24 849
    Points
    24 849
    Par défaut
    Cincap oublie le principale : TWindowsMediaPlayer
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    alors le code C en gros fait ceci

    1) rechercher la chaîne (ANSI) 'mvhd' dans le fichier et retourne 64 octets du fichier qui suivent
    2) il prend l'octet suivant qui contient la version, en version 1 il sauter 3 + 8 octets sinon 3 + 4
    3) il récupère 2 Cardinal qui sont timescale et timeunits qu'il swap pour avoir l'ordre Intel je suppose
    4) si les valeurs sont non nulles la durée c'est timeunits/timescale

    tu retrouves ça dans le PDF
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    aligned(8) class MovieHeaderBox extends FullBox(‘mvhd’, version, 0) {
     if (version==1) {
     unsigned int(64) creation_time;
     unsigned int(64) modification_time;
     unsigned int(32) timescale;
     unsigned int(64) duration;
     } else { // version==0
     unsigned int(32) creation_time;
     unsigned int(32) modification_time;
     unsigned int(32) timescale;
     unsigned int(32) duration;
     }
     template int(32) rate = 0x00010000; // typically 1.0
     template int(16) volume = 0x0100; // typically, full volume
     const bit(16) reserved = 0;
     const unsigned int(32)[2] reserved = 0;
     template int(32)[9] matrix =
     { 0x00010000,0,0,0,0x00010000,0,0,0,0x40000000 };
     // Unity matrix
     bit(32)[6] pre_defined = 0;
     unsigned int(32) next_track_ID;
    d'ailleurs on voit ici que duration est en 64bits en version 1 contrairement à ce que fait le code C...

    duration est exprimé en timescale, timescale c'est le nombre d'unité par seconde...d'où la division
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  8. #8
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut
    Bonjour Cincap,

    Merci, mais ta solution avec TWindowsMediaPlayer, fonctionne quand la vidéo est en cours de lecture ?

    Moi je voudrais connaitre la durée de la vidéo en testant le fichier MP4

    A+
    Charly

  9. #9
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut
    Merci Paul,
    avec ça je dois pouvoir me débrouiller

    A+
    Charly

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    par ailleurs en tapant "mvhd Delphi" sur Github j'ai trouvé ça

    https://github.com/dxzl/swiftmix-rad...e/M4aAtoms.pas
    https://github.com/ozok/TAudioConver...TagLibrary.pas

    j'ai pas creusé mais ça sent bon le parser du MP4
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  11. #11
    Membre confirmé Avatar de Galet
    Homme Profil pro
    Consultant/Programmeur Robotique industrielle
    Inscrit en
    Mars 2010
    Messages
    323
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Consultant/Programmeur Robotique industrielle

    Informations forums :
    Inscription : Mars 2010
    Messages : 323
    Points : 484
    Points
    484
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    ,
    @Galet : j'avais déjà vu ton premier lien. Pour la norme, ça à l'air compliqué, je n'ai pas trouvé la longueur de la vidéo (Duration ?)
    Tu trouveras le détail (et la confirmation des infos de Paul) dans la norme, en pages 15 et 16
    Nom : MP4_1.PNG
Affichages : 439
Taille : 26,2 Ko
    Nom : MP4_2.PNG
Affichages : 438
Taille : 181,9 Ko

    Belle journée,
    Images attachées Images attachées  
    Windows 10 / Delphi Tokyo
    "Les choses ne changent pas. Change ta façon de les voir, cela suffit" Lao Tseu

  12. #12
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 420
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 420
    Points : 1 325
    Points
    1 325
    Par défaut
    Bonjour à toutes et à tous,

    @ ShaiLeTroll, en effet, je travaille avec TWindowsMediaPlayer et j'ai loupé la commande utilisée par Charly910, cette commande je l'avais utilisée pour des fichiers .mp3, .mid, .wav.

    @ Charly910, si tu utilises ShellExecute et un fichier .bat tu sais connaitre la durée de ton média .mp4, (identique si tu doublecliques sur ton média et que cliques sur propriétés)

    A toi de construire ton module avec un TopenDialog ect...

    Bonne journée.

    @+,

    cincap

  13. #13
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 420
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 420
    Points : 1 325
    Points
    1 325
    Par défaut
    @ Charly910, voila j'ai fais des test avec plusieurs fichiers .mp4 et j'affiche la même durée indiquée dans la propriété du fichier.

    Le fichier .bat quelques lignes et la procédure ShellExecute.

    @+,

    cincap
    Images attachées Images attachées  

  14. #14
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut
    Bonjour,

    Merci à tous,

    je suis en train de décortiquer l’entête des fichiers MP4. Dès que mon code est au point je le poste.

    A+
    Charly

  15. #15
    Membre expérimenté
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    2 420
    Détails du profil
    Informations personnelles :
    Âge : 71
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2006
    Messages : 2 420
    Points : 1 325
    Points
    1 325
    Par défaut
    Bonjour à toutes et à tous,

    Celui qui veut peut télécharger une petite application légère en D6 qui indique la durée des fichiers .mp4, .mp3 et .wav identiquement à leur propriétés.

    Les fichiers vidéo ou audio doivent être dans le même dossier que l'application.

    @+,

    cincap
    Fichiers attachés Fichiers attachés

  16. #16
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    Citation Envoyé par Charly910 Voir le message
    Bonjour,

    Merci à tous,

    je suis en train de décortiquer l’entête des fichiers MP4. Dès que mon code est au point je le poste.

    A+
    Charly
    Bonjour,

    j'ai fait la même chose de mon coté.
    pour ne pas perturber ton idée j'attends que tu postes ton code ... et on pourra comparer si tu veux
    j'ai testé mon code avec plusieurs fichiers MP4 (des petits, des gros ...) et l'extraction des données se fait très vite (moins de 1 sec)
    peu importe la localisation des données dans le fichier (début/fin)
    N'ayant pas de MP4 avec entête 64bits cette partie n'est pas faite!!!

    Bon Dimanche
    Cordialement,
    @+

  17. #17
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut
    Bonjour,

    voici mon code très imparfait (de plus je ne traite que la version 0)
    Je ne doute pas que Cirec fasse 10 fois mieux !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    { ==================================================================================== }
    Function  TF_Princ.Duree( Video : String) : String ;
    //  Durée de la vidéo d'un fichier MP4
    { ----------------------------------------------------------------- }
      Function Byte2Hexa(Const Val: Byte) : String;
      //  converti un byte en Hexadecimal
      Const
        Lettre : Array[0..15] of String = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F') ;
      Var
        n, b   : integer ;
        Mess : String ;
      Begin
        b := Val Mod 16 ;
        n := Val div 16   ;
        Result := Lettre[n] + Lettre[b] ;
        Mess := 'Val : '+ IntToStr(Val) + ' n = '+ IntToStr(n)+' b = '+ InttoStr(b)+Chr(13) ;
        Mess := Mess + 'Lettre[n] = '+Lettre[n] + '  Lettre[b] = '+Lettre[b]+' Result = '+Result  ;
       end;
    { ----------------------------------------------------------------- }
      Function Swap(Hexa : String) :String ;
      //  Passe de littleEndian à BigEndian et vice versa
      Begin
        If (Length(Hexa) <> 8) Then
          Begin
            Result := '00000000' ;
            Exit ;
          End ;
        Result := Copy(Hexa, 5, 4)+ Copy(Hexa, 1, 4) ;
      End ;
    { ----------------------------------------------------------------- }
    Var
         Bin    : string ;
         Hex    : String ;
         Hex2    : String ;
         i      : integer ;
         Fs     : TFileStream ;
         bArray   : Array of Byte ;
         Taille : DWord ;
         Index1 : Integer ;
         Index2 : Integer ;
         Index3 : Integer ;
         TimeUnits : Int64 ;
         TimeScale : Int64 ;
         Duration  : Int64 ;
         Version   : Byte ;
         bb        : Byte ;
         Pos       : Integer ;
    Begin
      Fs := TFileStream.Create(Video,fmOpenRead) ;
      Taille := Fs.Size ;
      SetLength(bArray, Taille) ;
      Fs.Seek(0,soFromBeginning) ;
      Fs.Read(bArray[0],Taille) ;
      Fs.Free ;
      Bin := '' ;
      Hex2 := '' ;
      Hex := '' ;
      // Recherche de 'mvhd'
      For i := 0 to Length(bArray) -1 Do
        Begin
          Pos := i ;
          if bArray[i] = 109 Then
            if bArray[i+1] = 118 Then
              if bArray[i+2] = 104 Then
                if bArray[i+3] = 100 Then
                  Break ;
           Pos := -1 ;
        End ;
     
        If Pos = -1 Then     // 'mvhd' non trouvé
          Begin
            Result := 'Durée inconnue' ;
            Exit ;
          End ;
     
      Index1 := Pos ;              //  début du Chunk 'mvhd'
      Index2 := Index1+16 ;      //  position de TimeScale
      Index3 := Index2 + 4 ;     //  position de TimeUnits
     
      Version := bArray[Index1+4] ;
    //   ici il faut tester Version, mais pour le moment
    //   je ne traite que Version = 0
     
    // Extraction de TimeScale
      Hex2 := '' ;
      For i:= Index2 to Index2+3 do
        Hex2 := Hex2 +  Byte2Hexa(bArray[i]) ;
      Hex2 := Swap(Hex2) ;
      TimeScale := StrToInt64 ('$'+Hex2);
     
    // Extraction de TimeUnits
       Hex2 := '' ;
       For i:= Index3 to Index3+3 do
          Hex2 := Hex2 +  Byte2Hexa(bArray[i]) ;
        Hex2 := Swap(Hex2) ;
        TimeUnits := StrToInt64 ('$'+Hex2);
     
        Duration := TimeUnits div TimeScale ;
        Result := TimeToStr(Duration/24/3600);
    End ;
    { ==================================================================================== }
    Je vais regarder la solution de Cincap

    Merci à tous

    A+
    Charly

  18. #18
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 344
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 344
    Points : 3 122
    Points
    3 122
    Par défaut
    Bonjour Cincap,



    Ok ça fonctionne si le MP4 est dans le même répertoire que l'appli. Et c'est très rapide
    Comment fais tu ?

    A+
    Charly

  19. #19
    Membre éprouvé
    Avatar de Cirec
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    467
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 467
    Points : 1 072
    Points
    1 072
    Par défaut
    re,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
     
    const
      StrMoov: AnsiString = #$6D#$6F#$6F#$76#0#0#0#$6C#$6D#$76#$68#$64;
     
    type
      PMovieHeaderBox = ^TMovieHeaderBox;
      TMovieHeaderBox = packed record
        HeaderName: array[0..11] of AnsiChar;
        Version: Integer;
        case byte of
          0: (Creation_Time: Integer;
            Modification_Time: Integer;
            Timescale: Integer;
            Duration: Integer);
          1: (Creation_Time64: Int64;
            Modification_Time64: Int64;
            Timescale64: Integer;
            Duration64: Int64);
      end;
     
     
    function ByteSwap32(const A: Integer): Integer;
    asm
     BSWAP EAX        //
    end;
     
    function SecondToStrTime(Seconds: Integer): string;
    var
      HH, SC, MN, D: word;
    begin
      HH := Seconds div 3600;
      D := Seconds mod 3600;
      MN := D div 60;
      SC := D mod 60;
      Result := TimeToStr(EncodeTime(HH, MN, SC, 0));
    end;
     
    //*************************************************************************
    //*************************************************************************
    function GetMP4Duration(const aFileName: string): Integer;
    var
      FS: TFileStream;
      StrBuffer: AnsiString;
      A, B, LStrMoov, LStrBuffer: Int64;
    begin
      Result := -1;
      FS := TFileStream.Create(aFileName, fmOpenRead);
      try
        // recherche en début de fichier
        LStrMoov := Length(StrMoov);
        LStrBuffer := High(Word) * 2;
        SetLength(StrBuffer, LStrBuffer);
        FS.Read(StrBuffer[1], LStrBuffer);
        B := Pos(StrMoov, StrBuffer);
        if B = 0 then
        // si rien trouvé recherche en fin de fichier
        begin
          A := FS.Size;
          FS.Position := A;
          repeat
            Dec(A, LStrBuffer - LStrMoov);
            if A < 0 then A := 0;
            FS.Position := A;
            FS.Read(StrBuffer[1], LStrBuffer);
            B := Pos(StrMoov, StrBuffer);
          until (A = 0) or (B > 0);
        end;
        if B > 0 then
          // extraction et calcule de la durée
          with PMovieHeaderBox(@StrBuffer[B])^ do
            Result := ByteSwap32(Duration) div ByteSwap32(Timescale);
      finally
        FS.Free;
      end;
    end;
    //*************************************************************************
    //*************************************************************************
     
    // utilisation
    procedure TForm17.Button3Click(Sender: TObject);
    var
      Duration: Integer;
    begin
      OpenDialog1.FilterIndex := 2;
      if OpenDialog1.Execute then
      begin
        Duration := GetMP4Duration(OpenDialog1.FileName);
        if Duration > 0 then
        begin
          Label1.Caption := ExtractFileName(OpenDialog1.FileName);
          Label2.Caption := SecondToStrTime(Duration);
        end;
      end;
    end;
    Voilà le code est très rapide et simple à comprendre

    Cincap utilise un fichier bat et un vbs qui cré un objet Shell.Application
    on aurait pu le faire directement avec Delphi
    CreateOleObject('Shell.Application');

    Cordialement,
    @+

  20. #20
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 430
    Points
    28 430
    Par défaut
    ah tu as été plus rapide que moi

    voici ma version

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
     
    unit Unit1;
     
    interface
     
    uses
      Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
      System.DateUtils,
      Vcl.Graphics,
      Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Label1: TLabel;
        procedure Button1Click(Sender: TObject);
      private
        { Déclarations privées }
        function MP4Duration(const AFileName: string): string;
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    function LSwap(C: Cardinal): Cardinal;
    begin
      Result := Swap(C) shl 16 + Swap(C shr 16);
    end;
     
    function LLSwap(L: UInt64): UInt64;
    begin
      Result := LSwap(L) shl 32 + LSwap(L shr 32);
    end;
     
    function GetMP4Duration(const AFileName: string; var Duration: Int64): Boolean;
    type
      TMP4Chunk = packed record 
        Size: Cardinal;
        Tag : array[0..3] of AnsiChar;
      end;
      TMP4Mvhd = packed record
        Ver: Byte;
        Flags: array[0..2] of Byte;
        case Boolean of
          True: (
            Creation1, Modified1: UInt64;
            Timescale1: Cardinal;
            Duration1: UInt64;
          );
          False: (
            Creation2, Modified2: Cardinal;
            Timescale2: Cardinal;
            Duration2: Cardinal;
          );
        end;
    var
      S: TFileStream;
      H: TMP4Chunk;
      M: TMP4Mvhd;
    begin
      Result := False;
      S := TfileStream.Create(AFileName, fmOpenRead or fmShareDenyNone);
      try
        S.ReadBuffer(H, SizeOf(H)); // lecture d'un entête MP4
        if H.Tag <> 'ftyp' then // vérification du type
          Exit(False);
        repeat
          H.Size := LSwap(H.Size); 
          S.Seek(H.Size - SizeOf(H), TSeekOrigin.soCurrent); // sauter la section
          S.ReadBuffer(H, SizeOf(H)); // lire la suivante
        until H.Tag = 'moov'; // jusqu'au "moov"
        S.ReadBuffer(H, SizeOf(H)); // lire dans "moov"
        while H.Tag <> 'mvhd' do // jusque "mvhd"
        begin
          H.Size := LSwap(H.Size);
          S.Seek(H.Size - SizeOf(H), TSeekOrigin.soCurrent);
          S.ReadBuffer(H, SizeOf(H));
        end;
        S.ReadBuffer(M, SizeOf(M)); // lire son contenu
        if M.Ver = 1 then // en fonction de la version
        begin
          M.Duration2 := LLSwap(M.Duration2); // non testé !
          M.Timescale1 := LSwap(M.Timescale1);
          Duration := M.Duration1 div M.Timescale1;
        end else begin
          M.Duration2 := LSwap(M.Duration2);
          M.Timescale2 := LSwap(M.Timescale2);
          Duration := M.Duration2 div M.Timescale2; // calculé la durée en secondes
        end;
        Result := True;
      finally
        S.Free;
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      Str: string;
    begin
      if PromptForFileName(Str, '*.mp4') then
        Label1.Caption := MP4Duration(Str);
    end;
     
    function TForm1.MP4Duration(const AFileName: string): string;
    var
      Duration: Int64;
      H,M,S   : Word;
      Date    : TDateTime;
    begin
      if GetMP4Duration(AFileName, Duration) then
      begin
        M := Duration div 60;
        S := Duration - 60 * M;
        H := M div 60;
        Dec(M, H * 60);
        Date := Encodetime(H, M, S, 0); // durée en Time
        Result := TimeToStr(Date);  // pour faciliter le formatage
      end else begin
        Result := 'Unknown';
      end;
    end;
     
    end.
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Convertir une vidéo (au format MOV) au format AVI
    Par Mariion dans le forum Vidéo
    Réponses: 2
    Dernier message: 14/11/2010, 19h09
  2. une vidéo sous format .DAT
    Par Msysteme dans le forum Vidéo
    Réponses: 1
    Dernier message: 26/09/2010, 02h32
  3. Comment obtenir la durée d'une vidéo?
    Par bakabdel dans le forum ASP.NET
    Réponses: 0
    Dernier message: 13/04/2009, 13h39
  4. [Video] ouvrir une vidéo au format 3gp
    Par optitou dans le forum Vidéo
    Réponses: 5
    Dernier message: 26/03/2007, 09h56
  5. [TMediaPlayer] connaître la durée d'une vidéo
    Par jcs2 dans le forum Delphi
    Réponses: 5
    Dernier message: 29/08/2006, 19h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo