AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi Audiospur aus einer Avi-Datei extrahieren
Thema durchsuchen
Ansicht
Themen-Optionen

Audiospur aus einer Avi-Datei extrahieren

Ein Thema von capo · begonnen am 9. Jul 2008 · letzter Beitrag vom 26. Jul 2008
Antwort Antwort
Seite 1 von 2  1 2      
capo

Registriert seit: 7. Jul 2006
453 Beiträge
 
Delphi 11 Alexandria
 
#1

Audiospur aus einer Avi-Datei extrahieren

  Alt 9. Jul 2008, 22:39
Hallo...

ich habe folgendes Beispiel gefunden um eine Audiospur aus einer Avi-Datei zu extrahieren.
Bei kleinen Avi-Dateien funktioniert das ganz gut, bei großen Filmen gibt es immer Fehlermeldungen.
Zudem wird als *.wav gespeichert, ist aber keine richtige *.wav -Datei.

Es wäre schön wenn mir jemand dabei helfen kann.
Gefunden habe ich das Beispiel hier:
http://www.swissdelphicenter.ch/de/showcode.php?id=1309
Gruß
Vito


Delphi-Quellcode:
uses
{...}, vfw;

var
  abort: Boolean;

  {$R *.DFM}

{Vielen Dank an Jailbird, der einen großen Teil dieses Codes entwickelt hat
Special thanks to Jailbird, who developed a big part of this Code}


{Bitte zuerst die vfw.pas downloaden
Please download th vfw.pas first }


{Die 'SaveCallback' Funktion erlaubt es dem Benutzer den
aktuellen Prozess Status zu erfahren und den Speichervorgang
vorzeitig abzubrechen. Diese Funktion muss NICHT vom Benutzer
aufgerufen werden.

The 'SaveCallback' function allows the user to get the
process status and abort the save progress. This function
needn't to call by the user.}


function SaveCallback(nPercent: Int): Bool; pascal;
begin
  Application.ProcessMessages;

  Form1.Progressbar1.Position := nPercent; //Speicher Status in Prozent
  //Save Status in Percent
  if abort = True then
    Result := True //Wenn die Funktion "True" zurückgibt, wird der Speichervorgang fortgesetzt.
  else //If then function returns "True", the Process will continue
    Result := False; //Gibt sie "False" zurück wird der Vorgang abgebrochen
end; //If it returns "False" the process will abort


{Die folgende Funktion erwartet zwei Parameter:

Inputfile: PChar
  Geben Sie hier die die AVI Datei an aus welche Sie
  die Audiospur extrahieren möchten.

Outputfile: PChar
  Geben Sie einen Pfad + Dateinamen einer WAVE Datei an.
  In diese Datei wird die AudioSpur gespeichert.

  HINWEIS:
  Geben Sie nur eine WAVE Datei als Ausgabedatei an wenn
  die Audiodaten in der AVI Datei unkomprimiert (als PCM WAVE)
  vorliegen.

####################################################

The following function needs two parameters:

InputFile: PChar
  Enter a Dir + Filename of a AVI File.

OutputFile: PChar
  Enter a Dir + Filename of a WAVE File where do you want to
  put the audiodata of the movie.

  TIP:
  Enter jus a Filename of a WAVE File if the audiodata of the
  movie is in uncompressed PCM Format.

###########################################################

WICHTIG:
  Stellen Sie vor dem aufrufen der Funktion 'ExtractAVISound' sicher
  das die Eingabedatei (Inputfile) über eine AudioSpur verfügt.

IMPORTANT:
  Before calling the 'ExtractAVISound' function be sure that the
  Inputfile has a audiotrace.
}


function TForm1.ExtractAVISound(InputFile, Outputfile: PChar): Boolean;
var
  PFile: IAviFile;
  PAvi: IAviStream;
  plpOptions: PAviCompressOptions;
begin
  Abort := False;

  if Fileexists(StrPas(Outputfile)) then
  begin
    case MessageDlg('Ausgabedatei existiert bereits. Überschreiben?',
      mtWarning, [mbYes, mbNo], 0) of
      mrYes:
        begin
          DeleteFile(StrPas(Outputfile)); //Wichtig, da die Funktion sonst nur so viel der
        end; //Datei überschreibt wie gebraucht wird.
      //Important because the function overwrite just
      //the part of the file which is needed.
      mrNo:
        begin
          Exit;
        end;
    end;
  end;

  try //Initialisiert die API
    AviFileInit; //Init the API
    if AviFileOpen(PFile, Inputfile, 0, nil) <> 0 then //Öffnet eine AVI Datei
    begin //Opens a AVI File
      MessageDlg('Fehler beim laden des Videos.
Möglicherweise wird die Datei von einem anderen Prozess verwendet.
'
        + #13#10 +
        'Schließen Sie alle in Frage kommenden Anwendungen und versuchen Sie es erneut.',
        mtError, [mbOK], 0);
      Result := False;
      Exit;
    end;
    if AviFileGetStream(PFile, PAvi, StreamTypeAudio, 0) <> 0 then
    begin
      MessageDlg(
        'Fehler beim laden des AudioStreams. Bitte überprüfen Sie, ob dieses Video über einen AudioStream verfügt.',
        mtError, [mbOK], 0);
      AviFileExit;
      Result := False;
      Exit;
    end;
    //Speichert den AudioStream
    //Saves the AudioStream
    if AviSaveV(Outputfile, nil, @SaveCallback, 1, PAvi, plpOptions) <> 0 then
    begin
      MessageDlg('Fehler beim Speichern des AudioStreams oder Sie haben den Speichervorgang abgebrochen.',
        mtError, [mbOK], 0);
      AviStreamRelease(PAvi);
      AviFileExit;
      Result := False;
      Exit;
    end;
  finally
    AviStreamRelease(PAvi);
    AviFileExit;
  end;
  Result := True; //'TRUE' zurückgeben wenn alles geklappt hat
  //return 'TRUE' if all right
end;

//Beispiel zu aufrufen der Funktion:
//Example how to call the function:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if ExtractAVISound(PChar('D:\test.avi'), PChar('D:\test.wav')) = True then
    ShowMessage('Audiospur erfolgreich gespeichert!'); // Audio sucessfully saved
  else
    ShowMessage('Fehler beim Speichern der Audiospur.'); // Error while saving...
end;
Hotte
  Mit Zitat antworten Zitat
Benutzerbild von lbccaleb
lbccaleb

Registriert seit: 25. Mai 2006
Ort: Rostock / Bremen
2.037 Beiträge
 
Delphi 7 Enterprise
 
#2

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 9. Jul 2008, 23:51
mit nem bissel eigenprogrammierung, kannst du das auch mit dirext x und dem dspack machen!!
Martin
MFG Caleb
TheSmallOne (MediaPlayer)
Die Dinge werden berechenbar, wenn man die Natur einer Sache durchschaut hat (Blade)
  Mit Zitat antworten Zitat
Benutzerbild von littleDave
littleDave

Registriert seit: 27. Apr 2006
Ort: München
556 Beiträge
 
Delphi 7 Professional
 
#3

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 9. Jul 2008, 23:55
Also erstmal:
ich bezweifle, dass die Funktion function SaveCallback(nPercent: Int): Bool; pascal; die Aufrufkonvention "pascal" benutzen sollte. Ich denke eher, dass "stdcall" die richtige Aufrufkonvention ist - ist ja immerhin ein Windows-API-Callback.

Als nächstes
Zitat von capo:
Bei kleinen Avi-Dateien funktioniert das ganz gut, bei großen Filmen gibt es immer Fehlermeldungen.
Was kommen denn für Fehlermeldungen? Irgendwelche Exceptions Es wäre für alle sehr hilfreich, wenn du das noch konkretisieren würdest.

Zitat von cap:
Zudem wird als *.wav gespeichert, ist aber keine richtige *.wav -Datei.
Das ist nicht verwunderlich. Die Funktion, die du aufrufst, extrahiert einfach nur den Audio-Stream aus der Datei - mehr nicht. Der Audio-Stream kann ja auch ein MP3 sein, damit die Video-Datei kleiner wird. Die Funktion, die du aufrufst, konvertiert die Audio-Daten nicht, sie extrahiert diese nur. Afaik bietet diese API keine direkte Funktion zum De/Enkodieren von Audio-Dateien, das musst du selber machen oder externe Libraries dafür verwenden. Aber ich bin mir da nicht sicher.
Jabber: littleDave@jabber.org
in case of 1 is 0 do external raise while in public class of object array else repeat until 1 is 0
  Mit Zitat antworten Zitat
capo

Registriert seit: 7. Jul 2006
453 Beiträge
 
Delphi 11 Alexandria
 
#4

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 10. Jul 2008, 23:40
HI littleDave,
das pascal durch stdcall zu ersetzen war genau richtig.
Nun muss ich nur noch herausfinden ob der Audio-Stream Mp3 oder Wav kodiert ist.
Danke für deine Hilfe.
Gruß
Vito
Hotte
  Mit Zitat antworten Zitat
Ydobon

Registriert seit: 3. Mär 2006
261 Beiträge
 
Delphi 11 Alexandria
 
#5

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 11. Jul 2008, 18:55
Zitat von capo:
das pascal durch stdcall zu ersetzen war genau richtig.
Was eigentlich etwas verwundert, da pascal die von MS vorgegebene Aufrufkonvention für die Callback-Funktion ist. Meinen alten Programmen war es allerdings anscheinend egal, ob ich es darin gegen stdcall austausche.

Trotzdem würde ich lbccaleb Recht geben und DirectShow empfehlen, insbesondere wenn der Ton im richtigen Format auf die Platte soll. AVISaveV ist nun einmal nur dazu gedacht AVI-Dateien zu schreiben.
  Mit Zitat antworten Zitat
capo

Registriert seit: 7. Jul 2006
453 Beiträge
 
Delphi 11 Alexandria
 
#6

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 26. Jul 2008, 13:29
Ja, es klappt doch nicht so richtig, es gibt immer noch Fehler.
Hast du ein Beispiel für DirectShow und das extrahieren von Audiodaten?

Gruss
Capo
Hotte
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#7

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 26. Jul 2008, 15:03
Ich habe hier eine Bibliothek mit Beispielprogramm vorgestellt, die u.a. den Audiostream aus einer beliebigen Videodatei extrahiert und auf Platte speichert. Siehe:
http://www.delphipraxis.net/internal...t.php?t=138838
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat
capo

Registriert seit: 7. Jul 2006
453 Beiträge
 
Delphi 11 Alexandria
 
#8

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 26. Jul 2008, 15:27
Danke
Hotte
  Mit Zitat antworten Zitat
capo

Registriert seit: 7. Jul 2006
453 Beiträge
 
Delphi 11 Alexandria
 
#9

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 26. Jul 2008, 16:07
Hi...habe gerade mal damit rumtetestet, funktioniert super, das Extrahieren läuft in Echtzeit, gibt es eine schnellere Methode?

Gruss
Hotte
  Mit Zitat antworten Zitat
Benutzerbild von igel457
igel457

Registriert seit: 31. Aug 2005
1.622 Beiträge
 
FreePascal / Lazarus
 
#10

Re: Audiospur aus einer Avi-Datei extrahieren

  Alt 26. Jul 2008, 20:26
Schau dir doch mal den Sourcecode der Demo an (im Verzeichnis header\pascal\demos\ oder so). Lass einfach alles, das nicht mit Audio, sondern mit der Videowiedergabe zu tun hat weg - sprich alles wo "VideoDecoder" vorkommt. Dann erhälst du ungefähr folgendes Programm:

Delphi-Quellcode:
program acinerella_demo;

{$APPTYPE CONSOLE}

uses
  Windows, Classes, SysUtils, acinerella,
  AuWavout, SyncObjs;

type
  TWAVHdr = packed Record
    riff: array[0..3] of Char;
    len: DWord;
    cWavFmt: array[0..7] of Char;
    dwHdrLen: DWord;
    wFormat: Word;
    wNumChannels: Word;
    dwSampleRate: DWord;
    dwBytesPerSec: DWord;
    wBlockAlign: Word;
    wBitsPerSample: Word;
    cData: array[0..3] of Char;
    dwDataLen: DWord;
  end;

var
  inst: PAc_instance;
  pack: PAc_package;
  wave: TFileStream;
  wave_hdr: TWAVHdr;
  info: TAc_stream_info;
  audiodecoder: PAc_decoder;
  i: integer;
  fs: TFileStream;

function read_proc(sender: Pointer; buf: PChar; size: integer): integer; cdecl;
begin
  result := fs.Read(buf^, size);
end;

begin
  ReportMemoryLeaksOnShutdown := true;

  videodecoder := nil;
  audiodecoder := nil;
  wave := nil;

  if not FileExists(ParamStr(1)) then
  begin
    Writeln('Source file not specified. Simply drag and drop a video or an audio ' +
      'file on the executable. Press enter to close the program.');
    Readln;
    halt;
  end;
  
  fs := TFileStream.Create(ParamStr(1), fmOpenRead);
  fs.Position := 0;

  Writeln('Acinerella Pascal Test Program');
  Writeln('------------------------------');
  Writeln;

  inst := ac_init();

  ac_open(inst, nil, nil, @read_proc, nil);

  Writeln('Count of Datastreams: ', inst^.stream_count);
  for i := 0 to inst^.stream_count - 1 do
  begin
    Writeln;
    ac_get_stream_info(inst, i, @info);
    Writeln('Information about stream ', i, ':');
    case info.stream_type of
      AC_STREAM_TYPE_AUDIO:
      begin
        Writeln('Stream is an audio stream.');
        Writeln('--------------------------');
        Writeln;
        Writeln(' * Samples per Second: ', info.audio_info.samples_per_second);
        Writeln(' * Channel count : ', info.audio_info.channel_count);
        Writeln(' * Bit depth : ', info.audio_info.bit_depth);

        if audiodecoder = nil then
        begin
          audiodecoder := ac_create_decoder(inst, i);
          wave := TFileStream.Create(ExtractFilePath(ParamStr(0))+'out2.wav', fmCreate);

          with info.audio_info do
          begin
            wave_hdr.riff := 'RIFF';
            wave_hdr.len := 36;
            wave_hdr.cWavFmt := 'WAVEfmt ';
            wave_hdr.dwHdrLen := 16;
            wave_hdr.wFormat := 1;
            wave_hdr.wNumChannels := channel_count;
            wave_hdr.dwSampleRate := samples_per_second;
            wave_hdr.wBlockAlign := (channel_count * bit_depth) div 8;
            wave_hdr.dwBytesPerSec := (samples_per_second * bit_depth * channel_count) div 8;
            wave_hdr.wBitsPerSample := bit_depth;
            wave_hdr.cData := 'data';
            wave_hdr.dwDataLen := 0; //!Unknown
          end;

          wave.Write(wave_hdr, SizeOf(wave_hdr));
        end;
      end;
    end;
  end;

  Writeln;

  if not inst^.opened then
  begin
    Writeln('No video/audio information found. Press enter to leave.');
    Readln;
    exit;
  end;

  repeat
    Application.ProcessMessages;

    pack := ac_read_package(inst);
    if pack <> nil then
    begin
      if (audiodecoder <> nil) and (audiodecoder^.stream_index = pack^.stream_index) then
      begin
        if (ac_decode_package(pack, audiodecoder) > 0) then
        begin
          wave.Write(audiodecoder^.buffer^, audiodecoder^.buffer_size);
        end;
      end;
      
      ac_free_package(pack);
    end;
  until (pack = nil) or ((not frm.Visible) and (videodecoder <> nil));

  if audiodecoder <> nil then
    ac_free_decoder(audiodecoder);

  ac_close(inst);

  ac_free(inst);
  
  fs.Free;

  if wave <> nil then
  begin
    wave_hdr.len := wave.Size;
    wave_hdr.dwDataLen := wave.Size - sizeof(wave_hdr);

    wave.Position := 0;
    wave.Write(wave_hdr, sizeof(wave_hdr));

    wave.Free;
  end;
end.
Andreas
"Sollen sich auch alle schämen, die gedankenlos sich der Wunder der Wissenschaft und Technik bedienen, und nicht mehr davon geistig erfasst haben als die Kuh von der Botanik der Pflanzen, die sie mit Wohlbehagen frisst." - Albert Einstein
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 11:23 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz