Check if mms stream exists or not using PHP

2019-07-19 13:45发布

问题:

I am trying to write a php script to test if an mms:// stream exists or not. I have not been able to do it using php functions such as socket_connect/fopen/fsockopen/etc. I have been searching the web for hours now and found similar questions in other forums but no one has actually given an answer (or even whether this is possible).

This is a possible code that I've used with no luck:

PHP Code:

<?php
$socket = socket_create(AF_INET, SOCK_RAW, 1);
if(!$connect = socket_connect($socket, "mms://some.mms/stream", 1755) )
{
    echo 'Offline';
}
else
{
    echo 'Online';
}
?>

回答1:

You may want to look into using a video player with command line functionality, such as VLC. You can access it via PHP's intrinsic 'exec' function and parse the result. Alternatively, you could also use the FFMPEG library to open a stream and determine whether or not it exists/can be played.

FFMPEG: http://ffmpeg-php.sourceforge.net/
VLC: http://www.videolan.org/vlc/

Our company specializes in online streaming video and these we've run into some of the same issues; should give you a good starting point.

Also, here's a VERY OOOOOOOOLD bit of code I wrote to help us validate RTSP streams using PHP's socket_connect. You might derive some use out of it.

final static public function validateRTSP($url)
{
$url_bits = parse_url($url);

$port = isset($url_bits['port']) ? $url_bits['port'] : 554;

if(false == isset($url_bits['host']))
{
    throw new Exception("The URL `{$url}` does not have a valid host assignment.");
}

if(isset($url_bits['host']))
{
    if(false === $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP))
    {
        socket_close($socket);

        throw new Exception('A socket could not be opened: ' . socket_strerror(socket_last_error($socket)));
    }

    if(false === socket_connect($socket, $url_bits['host'], $port))
    {
        socket_close($socket);

        throw new Exception("A connection could not be established to {$url_bits['host']}: " . socket_strerror(socket_last_error($socket)));
    }

    $headers = array();

    $headers[] = "DESCRIBE {$url} RTSP/1.0";
    $headers[] = "User-Agent: WMPlayer/12.00.7600.16385 guid/3300AD50-2C39-46C0-AE0A-39E48EB3C868";
    $headers[] = "Accept: application/sdp";
    $headers[] = "Accept-Charset: UTF-8, *;q=0.1";
    $headers[] = "X-Accept-Authentication: Negotiate, NTLM, Digest";
    $headers[] = "Accept-Language: en-US, *;q=0.1";
    $headers[] = "CSeq: 1";
    $headers[] = "Supported: com.microsoft.wm.srvppair, com.microsoft.wm.sswitch, com.microsoft.wm.eosmsg, com.microsoft.wm.predstrm, com.microsoft.wm.fastcache, com.microsoft.wm.locid, com.microsoft.wm.rtp.asf, dlna.announce, dlna.rtx, dlna.rtx-dup, com.microsoft.wm.startupprofile";

    $headerString = implode("\r\n", $headers) . "\r\n\r\n";

    if(false === socket_write($socket, $headerString, strlen($headerString)))
    {
        socket_close($socket);

        throw new Exception("Could not send headers to {$url_bits['host']}: " . socket_strerror(socket_last_error($socket)));
    }


    $response = '';

    if(false === socket_recv($socket, $response, 2048, MSG_WAITALL))
    {
        socket_close($socket);

        throw new Exception("Could not read response from {$url_bits['host']}: " . socket_strerror(socket_last_error($socket)));
    }

    socket_close($socket);


    self::$passes[] = array
    (
        'request' => $headerString,
        'response' => $response
    );


    if(preg_match_all('#^RTSP/.*\s+302+\s#i', $response, $match))
    {
        preg_match_all('#(Location:\s(.*))\r\n#i', $response, $redirect_match);

        return self::url($redirect_match[2][0]);
    }

    if(false == preg_match('#^RTSP/.*\s+[200]+\s#i', $response))
    {
        throw new Exception("URL `{$url}` is invalid.");
    }

    if($attributes = array_pop(explode("\r\n\r\n", $response)))
    {
        preg_match_all("#([a-z]{1})={1}(.+)#i", $attributes, $all);

        self::$attributes = $all[0];
    }

    return true;
}


回答2:

Check the documentation of socet_connect(). The second parameter (address) must be an IPv4 or IPv6 address. I don't have experience with the mms stream, but my guess would be to connect to the server (with its IP) and then send the name of the socket (everything after mms://) to the server. I'd need more details about the MMS stream to assist you further.



回答3:

You cannot use the mms:// URL as second parameter. socket_connect() only takes a network address or server name there. With that raw socket function you can at best connect to the port, but not interact with a MMS server. Thus checking for the file path is not possible, unless you study this: http://msdn.microsoft.com/en-us/library/cc234711(PROT.10).aspx (At first glance a typical Microsoft binary protocol, with fixed width and/or null terminated strings.)



回答4:

I would recommend looking at implementing MMS in PHP. This should give you guidance to check the existance of a file (using the cURL library).

EDIT

Also, it appears the Microsoft Media Server (MMS) protocol isn't very well-known, and people have had problems trying to do what you are. Only recommendation (and I guess shot in the dark) would be use fsockopen and check for a response and go by that, otherwise it's a shot in the dark. As the linked Wikipedia page suggests, there are some who have tried reverse engineering the protocol, those may be your best bet.



标签: php mms