Music

Does anybody know how to play a mp3 file ALso does anyone know of a way to trigger an event after a songf is done playing Maybe get access to its length and time it or something

Steve




Answer this question

Music

  • Ganesha LD

    Moved from windows forms designer.

  • martinabc

    where would i be able to find these different SDKs and files



  • tk_vb

  • ottogbg

    or even simpler....bass.dll

  • Ricardo_AG

    You shoud use DirectX API or the managed directx, I don't have experience with the managed version but the native API is simple if you have to do simple things, such as play a file or get his duration; it is really difficult if you want to do "advanced" topics...
    After you install the directx sdk there's a lot of examples and documentation.

    for the events take a look at the EC_COMPLETE callback.

    Here some examples in delphi language, it should be clear to understand what they do,
    hope that helps.

    procedure EnumAudioDevices;
    var hr: HRESULT;
    pCreateDevEnum: ICreateDevEnum;
    pEnumCat: IEnumMoniker;
    pMoniker: IMoniker;
    pProp: IPropertyBag;
    pFilter: IBaseFilter;
    cFetched: LongInt;
    varName: OleVariant;
    count: LongInt;
    begin
    hr:= CoCreateInstance(CLSID_SystemDeviceEnum, nil,
    CLSCTX_INPROC_SERVER, IID_ICreateDevEnum,
    pCreateDevEnum);
    if FAILED(hr) then
    dxRaise(EDxGenericFailure, hr,
    'EnumAudioDevices: failed to create CLSID_SystemDeviceEnum');
    pCreateDevEnum.CreateClassEnumerator(CLSID_AudioRendererCategory, pEnumCat, 0);
    count := 0;
    while pEnumCat.Next(1, pMoniker, @cFetched) = S_OK do begin
    pMoniker.BindToStorage(nil, nil, IID_IPropertyBag, pProp);
    VariantInit(varName);
    if SUCCEEDED(pProp.Read('FriendlyName',varName,nil)) and
    (Pos('directsound', lowercase(varName)) > 0) and
    SUCCEEDED(pMoniker.BindToObject(nil, nil, IID_IBaseFilter, pFilter)) then begin
    System.SetLength(AudioDeviceStrings, count + 1);
    System.SetLength(AudioDeviceMoniker, count + 1);
    AudioDeviceStrings[count]:= varName;
    AudioDeviceMoniker[count]:= pMoniker;
    Inc(Count);
    System.SetLength(AudioDeviceStrings,Count + 1);
    end;
    VariantClear(varName);
    pMoniker := nil;
    end;
    System.SetLength(AudioDeviceStrings, count);
    System.SetLength(AudioDeviceMoniker, count);
    end;
    // ............................................................................

    function GetAudiofileDuration(aFilename: string): longint;
    var mediadetails: IMediaDet;
    res: HRESULT;
    dur: double;
    n: integer;
    ws: widestring;
    begin
    result := 0;
    ws := aFilename;
    if (not fileExists(aFileName)) then exit;
    try CoCreateInstance(CLSID_MediaDet, nil, CLSCTX_INPROC_SERVER,
    IID_IMediaDet, mediadetails);
    if mediadetails = nil then exit;
    res := mediadetails.put_Filename(PWideChar(ws));
    if FAILED(res) then Exit;
    res := mediadetails.get_OutputStreams(n);
    if FAILED(res) or (n = 0) then Exit;
    res := mediadetails.put_CurrentStream(0);
    if FAILED(res) then Exit;
    res := mediadetails.get_StreamLength(dur);
    if FAILED(res) then Exit;
    result := round(dur * 1000);
    except
    end;
    end;

    constructor TDxFilePlayer.Create(deviceParams: TFilePlayerDeviceParams;
    fileParams: TFilePlayerParams; aLogFilename: string = '');
    var mk: IMoniker;
    pI, pF: int64;
    begin
    if instances = high(instances) then instances := 0;
    inc(instances);
    inst := instances;
    if (not odd(inst)) then spaces := ' '
    else spaces := '';
    //spaces := '[' + IntToHex(inst, 8) + ']' + spaces;
    devparms := deviceParams;
    fileparms := fileParams;
    //
    if (aLogFilename <> '') then SetLog(aLogFilename);
    logRef('create');
    logWrite('create TDxFilePlayer');
    logWrite('- fileparms = ' + fileParamsStr(fileParams));
    logWrite('- devparms.moniker = ' + devparms.MonikerName);
    //
    hwnd := CreateWindowHandle(Self);
    flags.state := psError;
    FUserVol := False;
    FCapabilities := [canPlay, canStop, canPause, canRewind, canFadeIn,
    canFadeOut, canSetVolume, canSetUserVolume, canMix,
    canLoop, canPlayWithoutMarks, canChangeLoopMode];

    // create the directx graph
    CoCreateInstance(CLSID_FilterGraph,
    nil,
    CLSCTX_INPROC_SERVER,
    IID_IFilterGraph2,
    graph);
    FLastErr := iEvents.SetNotifyWindow(hwnd, WM_GRAPHEVENT, 0);
    if FAILED(FLastErr) then
    dxRaise(EDxInvalidAudioDevice, FLastErr,
    'cannot setup callback events');
    logWrite('filter graph created');

    // get the audio out moniker
    try mk := audiodev.MonikerByName(devparms.MonikerName);
    if (mk = nil) then mk := audiodev.Moniker(devparms.MonikerNum);
    except
    raise EDxInvalidAudioDevice.Create('moniker name and num are both invalid');
    end;
    if (mk = nil) then
    raise EDxInvalidAudioDevice.Create('moniker name and num are both invalid');
    logWrite('moniker ok');

    // acquire the audio render
    FLastErr := mk.BindToObject(nil, nil, IID_IBaseFilter, audioRender);
    if FAILED(FLastErr) then
    dxRaise(EDxInvalidAudioDevice, FLastErr,
    'cannot access audio device');
    logWrite('audioout filter ok');

    // add the audio render to the filter graph
    FLastErr := graph.AddFilter(audioRender, 'audioRender');
    if FAILED(FLastErr) then
    dxRaise(EDxInvalidAudioDevice, FLastErr,
    'cannot add audioRender to the filter graph');
    logWrite('audiorender ok');

    // let directx build the rest of the filter graph for us
    FLastErr := graph.RenderFile(PWideChar(fileparms.FileName), nil);
    if FAILED(FLastErr) then
    dxRaise(EDxInvalidAudioDevice, FLastErr,
    'cannot render file "' + fileparms.FileName + '"');
    logWrite('renderfile ok');

    // get preroll, som & dur
    fileparams.Preroll := 0;
    if SUCCEEDED(iSeek.GetPreroll(pF)) then
    fileparams.Preroll := pF div HNS_PER_FRAME;
    logWrite('preroll is ' + IntToStr(fileparams.Preroll) + ' frames');
    fileparams.FileSOM := 0;
    fileparams.FileDUR := 0;
    if SUCCEEDED(iSeek.GetDuration(pF)) then
    fileparams.FileDUR := pF div HNS_PER_FRAME;

    // set markin & markout
    if fileparms.withoutMarks then begin
    FLastErr := iSeek.GetDuration(pF);
    if FAILED(FLastErr) then
    dxRaise(EDxInvalidAudioDevice, FLastErr,
    'cannot retrieve duration');
    fileparms.MarkIn := 0;
    fileparms.MarkOut := pF div HNS_PER_FRAME;
    fileparms.CrossPoint := fileparms.MarkOut;
    logWrite('- fileparms updated = ' + fileParamsStr(fileParams));
    end;
    pI := int64(fileparms.MarkIn) * HNS_PER_FRAME; // pI is in 100 nanosec
    pF := int64(fileparms.MarkOut) * HNS_PER_FRAME; // pI is in 100 nanosec
    logWrite('set positions to ' + IntToStr(pI) + ', ' + IntToStr(pF));
    FLastErr := iSeek.SetPositions(pI, AM_SEEKING_ABSOLUTEPOSITIONING,
    pF, AM_SEEKING_ABSOLUTEPOSITIONING);
    if FAILED(FLastErr) then
    dxRaise(EDxInvalidAudioDevice, FLastErr,
    'cannot set MarkIn/MarkOut');
    logWrite('positions set');

    // final settings
    flags.init(fileparms);
    iAudio.put_Volume(flags.volIn);
    flags.state := psStop;
    SetLoopMode(fileparms.loopMode);
    logWrite('flags set');

    // call inherited create and launch thread
    inherited;
    logWrite('thread launched');
    logResult('creation');
    end;

  • CJ Patrick

    WMP SDK has never helped.

    Take it easy MVP....google is not a mouthwash.



  • MrZap

    or to make life that bit simple, use the WMP SDK.

  • AJMRepetto

  • SivaS

    that really doesn't help - what is bass.dll how do you use it how would you implement it

  • kevin D. white

    Good to go. how do i use the plugin in vb



  • Music