Hello, I'm using code as shown below to play the first duration milliseconds of a media file

MCIWndHome(m_Audio);	
MCIWndPlayTo(m_Audio, duration);

This works fine to only play the first duration milliseconds when the length of the audio file is greater than duration, but if the audio is longer than that I get the error "The specified parameter is out of range for the specified command."
The documentation says:

The MCIWndPlayTo macro plays the content of an MCI device from the current position to the specified ending location or until another command stops playback. If the specified ending location is beyond the end of the content, playback stops at the end of the content.

So I figured I could put whatever I want in for the ending location and it would always either stop at the specified end location or at the end of the media, whichever comes first. Instead I get the error and it doesn't play at all.

What am I doing wrong? Why wouldn't this work?

Dani AI

Generated

Short answer: the numeric "to" passed to MCIWndPlayTo is interpreted in the MCI device's current time format (milliseconds, frames, samples, bytes, etc.), so passing a millisecond value when the device is using a different format can produce an out-of-range error. The MCIWnd macros use the device time format for seek/play operations; the units therefore must match the device's current format. (learn.microsoft.com)

A reliable approach is to force or check the time format before issuing PlayTo. The VFW helper macros let an MCIWnd window be set to milliseconds (so a millisecond duration value is valid), or the code can query the current format and convert units appropriately. Example (new code only — not the workaround posted earlier):

MCIWndUseTime(hMciWnd);                 // request milliseconds for this device
char fmtName[64];
MCIWndGetTimeFormat(hMciWnd, fmtName, sizeof(fmtName)); // confirm format string

See the MCI time-format documentation for the supported formats and how to set them. (learn.microsoft.com)

The documentation does say PlayTo should stop at the end if the requested end is beyond the content, but MCI is implemented by device drivers and some drivers will still return an out-of-range error instead of silently clamping. For that reason clamping the "to" value to the device length (the approach discovered by ) is the pragmatic, robust fix for diverse files and drivers. Use the MCIWndGetLength (or MCIWNDM_GETEND) helper to obtain the device length and clamp before calling PlayTo. (learn.microsoft.com)

Extra troubleshooting tips: if PlayTo still fails, retrieve the textual MCI error with MCIWndGetError or enable MCIWNDF_NOTIFYERROR to receive notifications; this usually gives the driver reason text. For modern work, Microsoft recommends using MediaPlayer/Media Foundation APIs instead of the legacy MCI/MCIWnd class for more predictable behavior with streaming and modern codecs. (learn.microsoft.com)

Summary: forcing/checking the time format (milliseconds) and clamping the play-to value to the reported length is the practical solution; ’s workaround is correct and portable across MCI drivers.

Any idea why this code doesn't appear to be performing as described in the documentation?

If anyone else has this problem, below is the workaround that I've put in for now that seems to do the trick, although it's still not clear to me why it doesn't work the original way.

int len = MCIWndGetLength(m_Audio);	
if(len > max_duration) len = max_duration;
MCIWndPlayTo(m_Audio, len);

Instead of screwing around with finding the length, comparing it with the maximum duration I want and playing to whichever is shorter, I'd still like to know why it doesn't do this:

If the specified ending location is beyond the end of the content, playback stops at the end of the content.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.