TROGDOR has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow PerlMonks,

I'm trying to play an MP3 file in a game I'm writing with my son. The code is fairly simple:

use Win32::MediaPlayer; use Cwd; print "Current directory is ". getcwd . "\n"; $winmm = new Win32::MediaPlayer; $winmm->load('c:/dev/roar.mp3'); print "Here.\n"; $length = $winmm->length; print "length is $length\n"; $winmm->volume(100); $winmm->play; print "Done.\n";
The resulting output when run from a command prompt is:
C:\dev>perl game.pl Current directory is C:/dev Here. No File Loaded at C:/Perl/site/lib/Win32/MediaPlayer.pm line 58. length is 1453 No File Loaded at C:/Perl/site/lib/Win32/MediaPlayer.pm line 44. Done.
When I run this, I hear no sound. I can play the roar.mp3 file in winamp with no problem. The roar.mp3 file is in the same directory as the game.pl file. The odd part is, the length echo is correct. The mp3 file is 1.453 seconds long. So how could the program know the length of the mp3 file if it supposedly did not load correctly?

I'm running this on Windows XP. I just installed the MediaPlayer module today. Any ideas why it's not playing? Can anyone offer an alternative suggestion for playing an mp3? (Since it's for a game, I want it to play embedded, without a player popping up.)

Thanks,
TROGDOR

Replies are listed 'Best First'.
Re: Win32::MediaPlayer not playing sound
by toolic (Bishop) on Jan 02, 2012 at 01:05 UTC
Re: Win32::MediaPlayer not playing sound
by BrowserUk (Patriarch) on Jan 02, 2012 at 06:38 UTC

    Looking at the source of the module, it sets: $self->{play} = 0; in new().

    And it issues the warning you are seeing from ->length() in line 58:

    warn 'No File Loaded' if($self->{play}==0);

    and ->volume() in line 44:

    warn 'No File Loaded' if($self->{play}==0);

    But ->load(), successful or not, doesn't set that variable:

    sub load { my $self = shift; my $file = shift; $result = doMM("open \"$file\" type mpegvideo alias ".$self->{alias}); return $result; }

    Only ->play() does:

    sub play { my $self = shift; my $pos = shift || $self->{pos}; $self->{play} = 1; $result = doMM("play ".$self->{alias}." from $pos"); return $result; }

    And it sets it regardless of whether the attempt to play the file was successful or not.

    This doesn't help you fix your program, but it -- along with the lack of indentation and other clues in the source code; the age of the bug reports on RT; -- may give you an indication of the quality of this module and your chances of solving the problem.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

    The start of some sanity?

Re: Win32::MediaPlayer not playing sound
by GrandFather (Saint) on Jan 02, 2012 at 01:49 UTC
Re: Win32::MediaPlayer not playing sound
by Anonymous Monk on Jan 02, 2012 at 04:11 UTC

    I would try using the older wheel Win32::MCI::Basic / Win32::MCI::CD , it comes with mciGetErrorString

    site:perlmonks.org Win32::MCI -> Get CDDB info on Win32

    update: And it works on WinXP :)

    #!/usr/bin/perl -- use strict; use warnings; use Win32::MCI::Basic; Main( @ARGV ); exit( 0 ); sub Main { my $sFileName = shift or die "Usage: $0 C:\media\sh-boom.mp3 \n"; Shabba( qq{open "$sFileName" alias MediaFile } ); # OK! ## http://msdn.microsoft.com/en-us/library/ms709461%28v=VS.85%29.aspx# + MCI my $length = Shabba( qq{status MediaFile length } ); Shabba( qq{play MediaFile from 0 } ); my $position = Shabba( qq{status MediaFile position} ); while ( $position < $length ){ sleep 1; $position = Shabba( qq{status MediaFile position} ); } Shabba( qq{close MediaFile } ); } sub Shabba { my $lpszCommand = shift; my ( $APICallReturnValue, $lpszReturnString ) = mciSendString($lps +zCommand); my $lpszErrorText = mciGetErrorString( $APICallReturnValue ); no warnings 'uninitialized'; print " \$lpszCommand : $lpszCommand \$APICallReturnValue : $APICallReturnValue \$lpszReturnString : $lpszReturnString \$lpszErrorText : $lpszErrorText ---- "; return $lpszReturnString ; } __END__

    update: Win32::MediaPlayer has $mciSendString = new Win32::API( "winmm", "mciSendString", ['P', 'P', 'N', 'N'], 'N' )

    Where as Win32::MCI::Basic has  new Win32::API('winmm',    'mciSendString',    ['P','P','I','P'],    'N');

    Sometimes old wheels are better :)