2011-11-12 3 views
1

난 그냥이mjpeg 방송의 병목 현상은 어디에 있습니까?

<?php 
//example /cli/watch.php?i=0&j=200 

function get_one_jpeg($i) { 
    $path = "img"; 
    //$f = fopen("$path/$i.jpg", "rb"); 
    return file_get_contents("$path/$i.jpg"); 
} 
ini_set('display_errors', 1); 
# Used to separate multipart 
$boundary = "my_mjpeg"; 

# We start with the standard headers. PHP allows us this much 
//header("Connection: close"); 
header("Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0"); 
header("Cache-Control: private"); 
header("Pragma: no-cache"); 
header("Expires: -1"); 
header("Content-type: multipart/x-mixed-replace; boundary=$boundary"); 

# From here out, we no longer expect to be able to use the header() function 
print "--$boundary\n"; 

# Set this so PHP doesn't timeout during a long stream 
set_time_limit(0); 

# Disable Apache and PHP's compression of output to the client 
@apache_setenv('no-gzip', 1); 
@ini_set('zlib.output_compression', 0); 

# Set implicit flush, and flush all current buffers 
@ini_set('implicit_flush', 1); 
for ($i = 0; $i < ob_get_level(); $i++) 
    ob_end_flush(); 
ob_implicit_flush(1); 

# The loop, producing one jpeg frame per iteration 
$i = $_GET['i']; 
$j = $_GET['j']; 

while ($i <= $j) { 
    # Per-image header, note the two new-lines 
    print "Content-type: image/jpeg\n\n"; 

    # Your function to get one jpeg image 
    print get_one_jpeg($i); 

    # The separator 
    print "--$boundary\n"; 

    # Sleeping for 0.1 seconds for 10 frames in second 
    usleep(100000); 

    $i++; 
} 
?> 

처럼 PHP와 MJPEG 스트리밍하지만 이미지의 큰 범위를 설정하는 경우, 예를 들어, 0에서 300까지, 한정없는 때 브라우저에서 바로 표시를 중지하고 있습니다.

특정 프레임이나 순간이 아니며 다른 브라우저에서 표시되므로 Apache의 원인은 Apache라고 생각합니다.

나는 아파치 2.2.9와 2.2.21에서 시험해보고 같은 결과를 얻었다. IIS Express에서는 더욱 악화됩니다.

어떤 문제가있을 수 있습니까?

+0

파일을 포함 할 때'$ _GET' 변수를 직접 사용하지 마십시오. 심각한 보안 문제가 발생할 수 있습니다! – gnur

+0

의견을 보내 주셔서 감사합니다. 테스트 용으로 만 사용합니다. – Saito

답변

1

만 주어진 정보에 기초하여 다음 프레임 크기/해상도가 크면 초당

10 프레임 MJPEG 용 조금 공격적 일 수있다. 이것은 정적 인 프레임 부분이 전송되지 않는 mpeg가 아니라는 것을 기억하십시오. 여기서 전체 프레임/이미지가 매번 전송됩니다. 먼저 프레임 속도를 약 5로 낮추려고합니다. 문제가 개선되면 문제는 데이터 속도입니다. 어딘지/어떻게 든됩니다. 코드가 일부 프레임을 버퍼링 한 다음 버퍼에서 읽을 경우 10fps로 문제를 개선 할 수 있습니다. 그렇게하면 프레임이 느려져서 코드 나 브라우저가 나타나지 않습니다. 나는 또한 다음 이미지를 포기하고 계속하기 전에 코드가 이미지가 나타날 때까지 기다리는 시간을 제한해야한다고 생각합니다. 희망이 도움이됩니다.

1

이 질문이 유효한지 확실하지 않지만 그렇지 않은 경우에도 직접적인 대답은 없습니다.

"이미지가 손상되거나 잘 렸습니다"라는 오류가 발생한다고 가정합니다. 내 코드는 거의 동일하며 usleep (..)을 사용할 때 같은 문제가 발생했습니다.

근원은 usleep (..) 배치입니다. print ($ boundary) 전에 호출해야합니다. 인쇄 후 배치하면, 브라우저는 경계 섹션 직후의 이미지를 기대하고 있기 (위해) 때문에, 무엇인가 잘못되어 버리는 것이됩니다. 이 코드에서는 경계가 100ms 동안 스트림을 보유하고있는 usleep (..) 바로 뒤에 있고 브라우저 때문에 뭔가 잘못되었다고 생각합니다.

변경이 코드 :

print "--$boundary\n"; 
usleep(100000); 

한이 사람 :

usleep(100000); 
print "--$boundary\n"; 

그리고 모든 것이 작동 잘 될 것입니다.