Ripping by Using IWMPPlayerServices::setTaskPane

[The feature associated with this page, Windows Media Player SDK, is a legacy feature. It has been superseded by MediaPlayer. MediaPlayer has been optimized for Windows 10 and Windows 11. Microsoft strongly recommends that new code use MediaPlayer instead of Windows Media Player SDK, when possible. Microsoft suggests that existing code that uses the legacy APIs be rewritten to use the new APIs if possible.]

Note

This section documents a feature of the Windows Media Player 9 Series and Windows Media Player 10 ActiveX controls. It is recommended that you use the IWMPCdromRip interface with later versions. See IWMPCdromRip Interface.

 

You can use the Windows Media Player 9 Series or later control to copy CD tracks to the user's computer. This process is called ripping. To do this, you must embed the Windows Media Player control in remote mode. For more information about remote mode, see Remoting the Windows Media Player Control.

To start the ripping process, call IWMPPlayerServices::setTaskPane, passing the CopyFromCD?AutoCopy:id value for the bstrTaskPane parameter, where id is the index of the CD drive from which to copy. This index corresponds to the index of a Cdrom object in the IWMPCdromCollection interface or the CdromMediaChange event.

The following example code is a function that starts the process of ripping a CD from the CD drive identified by index zero. The function uses the following member variable:

CComPtr<IWMPPlayer4>  m_spPlayer;  // Smart pointer to IWMPPlayer4.

The following code shows the body of the function:

HRESULT CMyApp::StartRip()
{
    CComPtr<IWMPPlayerApplication>  spPlayerApp;
    CComPtr<IWMPPlayerServices>     spPlayerServices;
    CComBSTR bstrParam;  // Contains the parameter string.

    ATLASSERT(m_spPlayer.p);

    HRESULT hr = m_spPlayer->QueryInterface(&spPlayerServices);

    if(SUCCEEDED(hr))
    {
        // Create the parameter string.
        hr = bstrParam.Append(_T("CopyFromCD?AutoCopy:0"));
    }

    if(SUCCEEDED(hr))
    {
        // Rip the CD in drive 0.
        hr = spPlayerServices->setTaskPane(bstrParam);
    }

    return hr;
}

Displaying Status to the User

When copying from a CD, you can retrieve a string containing status information about the copy operation. To do this, you must first retrieve a playlist containing media items that represent the CD tracks by calling IWMPCdrom::get_playlist. Like the previous example, the following example code works with CD drive index zero. It stores the retrieved playlist in the following member variable:

CComPtr<IWMPPlaylist>  m_spCDPlaylist;

The following code shows the body of the function:

HRESULT CMyApp::GetCDPlaylist()
{
    HRESULT hr = S_OK;

    // Release any existing playlist instance.
    m_spCDPlaylist.Release();

    CComPtr<IWMPCdromCollection> spCDDrives;
    CComPtr<IWMPCdrom>  spDrive;
    long lCount = 0;  // Count of CD drives.

    ATLASSERT(m_spPlayer);

    hr = m_spPlayer->get_cdromCollection(&spCDDrives);

    // Test to make sure there is at least one drive.
    if(SUCCEEDED(hr))
    {
        hr = spCDDrives->get_count(&lCount);
    }

    if(SUCCEEDED(hr) && lCount < 1)
    {
        MessageBox(_T("No CD drive detected"), 
                   _T("CD Rip Error"), MB_OK);
        hr = NS_E_CD_READ_ERROR;
    }

    if(SUCCEEDED(hr))
    {
        // Retrieve the first drive.
        hr = spCDDrives->item(0, &spDrive);
    }
    
    if(SUCCEEDED(hr))
    {
        // Get the playlist.
        hr = spDrive->get_playlist(&m_spCDPlaylist);
    }
   
    return hr;
}

Next, handle the IWMPEvents::MediaChange event. This event occurs when a CD track is being ripped. The IDispatch pointer passed to the event handler points to the IWMPMedia interface for the CD track. Call QueryInterface through IDispatch to retrieve the pointer to IWMPMedia.

To detect which CD track is being ripped, compare the IWMPMedia pointer from the event to the media items in the CD playlist by calling IWMPMedia::get_isIdentical.

Call IWMPMedia::getItemInfo, passing the string "Status" as the item name. Status is a temporary attribute set by Windows Media Player on media items while they are being ripped from CD; it is not available from the library.

The following example code shows a MediaChange event handler.

void CMyApp::MediaChange(IDispatch * Item)
{
    // Test whether the CD playlist exists.
    if(!m_spCDPlaylist)
    {
        return;
    }

    // Declare and initialize variables.
    CComPtr<IWMPMedia> spMedia;
    HRESULT hr = S_OK;
    VARIANT_BOOL vbIdentical = VARIANT_FALSE;
    CComBSTR bstrVal;
    CComBSTR bstrName;
    long lCount = 0;  

    // Create the attribute value string.
    hr = bstrName.Append(_T("Status"));

    if(SUCCEEDED(hr))
    { 
        // Retrieve the IWMPMedia pointer from IDispatch.
        hr = Item->QueryInterface(__uuidof(IWMPMedia),(void**)&spMedia);
    }

    if(SUCCEEDED(hr))
    {
        // Get the value of the Status attribute.
        hr = spMedia->getItemInfo(bstrName, &bstrVal);
    }

    if(SUCCEEDED(hr))
    {
        // If the attribute is empty, set a failure code
        // to simply exit the function.
        if(bstrVal.Length() == 0)
        {
            hr = E_PENDING;
        }
    }
      
    if(SUCCEEDED(hr))
    {
        // Retrieve the count of items in the CD playlist.
        hr = m_spCDPlaylist->get_count(&lCount);
    }

    if(lCount < 1)
    {
        // Exit if the playlist is empty.
        hr = E_PENDING;
    }    

    if(SUCCEEDED(hr) && spMedia)
    {
        // Iterate through the playlist.
        // Compare the media item that raised the event
        // to each CD track. This detects which track
        // has a new status.
        for(long i = 0; i < lCount; i++)
        {
            CComPtr<IWMPMedia> spTrack;

            // Retrieve the CD track as a media object.
            hr = m_spCDPlaylist->get_item(i, &spTrack);

            if(SUCCEEDED(hr))
            {
                // Do the comparison.
                hr = spMedia->get_isIdentical(spTrack, &vbIdentical);
            }

            if(SUCCEEDED(hr) && VARIANT_TRUE == vbIdentical)
            {
                 // spTrack represents a track with changed status.
                 // bstrVal contains a status string. For example:
                 // "Ripping (10%)"
                 //
                 // TODO: Retrieve metadata about the track, and then
                 // display the status to the user.
            }
        }
    }

    return;
}

IWMPCdrom Interface

IWMPCdromCollection Interface

IWMPEvents Interface

IWMPMedia Interface

IWMPPlayerServices Interface

IWMPPlaylist Interface

Player Control Guide

Ripping by Using the IWMPCdromRip Interface