2014-04-25 2 views
13

나는 30 FPS 비디오 스트림을 렌더링 한 다음 실시간으로 WebM Byte Stream으로 인코딩 및 멀티플렉싱하는 서버 응용 프로그램을 보유하고 있습니다.라이브 MediaSource 비디오 스트림을 동기화 상태로 유지하는 방법은 무엇입니까?

클라이언트 측에서 HTML5 페이지는 연결을 수락 할 때 스트림 생성을 시작하는 WebSocket을 서버에 엽니 다. 헤더가 전달 된 후에는 각각의 WebSocket 프레임이 하나의 WebM SimpleBlock으로 구성됩니다. 키 프레임은 매 15 프레임마다 발생하고 새로운 클러스터가 시작될 때 발생합니다.

또한 클라이언트는 MediaSource을 만들고 WS에서 프레임을 수신하면 내용을 활성 버퍼에 추가합니다. <video>은 첫 번째 프레임이 추가 된 직후에 재생을 시작합니다.

모든 것이 적절하게 작동합니다. 나의 유일한 문제는 네트워크 지터로 인해 재생 위치가 잠시 후 실제 시간에서 벗어나게된다는 것입니다. 현재 해결 방법은 updateend 이벤트에 연결하고 수신 클러스터의 video.currentTime과 시간 코드의 차이를 확인하고 허용 범위를 벗어날 경우 currentTime을 수동으로 업데이트하십시오. 불행하게도, 이것은 눈에 띄는 일시 정지와 다소 불쾌한 재생에서의 점프를 야기합니다.

해결책도 조금 이상합니다. 최신 키 프레임의 위치를 ​​정확히 알고 있지만 currentTime에 전달하기 전에 전체 키 프레임을 전체 초 (W3C 사양에 따라)로 변환해야합니다. 브라우저는 아마도 그 다음에 가야하고 가장 가까운 키 프레임을 찾아야합니다.

내 질문은 : 미디어 요소에 항상 최신 키 프레임을 검색하도록 요청하거나 재생 시간을 시스템 시간과 동기화하도록 설정하는 방법이 있습니까?

+0

솔루션을 찾았습니까? –

+0

currentTime을 변경하는 솔루션이 최고라는 것을 깨달았습니다. 그 원인은 네트워크 결함으로 인해 버퍼가 증가하여 문제를 해결할 수있는 또 다른 결함이 정상적이기 때문입니다. 스트림 중에 연속적인 연결 문제가있는 경우 글리치가 발생합니다. –

답변

3

네트워크 지터는 재생 위치가 문제가 아니에요

드리프트됩니다. 스트림에서 드롭 아웃이 발생하면 재생을 시작하기 전에 충분한 버퍼링을 수행하지 못하고 실시간으로 몇 초 뒤에 (정상적인 경우에도) 재생에는 적절한 크기의 버퍼가 있습니다.

내 현재 솔루션은 updateend 이벤트에 후크 정확한 방법에 가까이 수신 클러스터

에 video.currentTime 시간 코드의 차이를 확인하기위한 것이다. 들어오는 클러스터의 시간 코드를 무시하고 대신 버퍼링 된 시간 범위를 검사하는 것이 좋습니다. WebM 클러스터에서받은 내용과 해독 된 내용은 서로 다른 두 가지 사항입니다.

불행하게도, 이는 일시적인 멈춤을 유발하고 재생시 점프하여 다소 불쾌합니다.

다른 방법은 무엇입니까? 실시간으로 건너 뛰거나 재생 속도를 높이면 실시간을 따라 잡을 수 있습니다. 어느쪽으로 든, 당신이 실시간에 따라 잡기를 원한다면, 당신은 그것을 할 시간 내에 건너 뛰어야 만합니다. 나는 최신 키 프레임

당신은 할 수있다 정확히 어디 있는지,하지만 미디어가 디코딩 될 때까지 플레이어는하지 않습니다

또한이 솔루션은 약간 이상한 느낌.어쨌든 키 프레임은 관련이 없습니다 ... 키 프레임이 아닌 위치를 찾을 수 있습니다. 브라우저는 필요에 따라 P/B- 프레임보다 먼저 디코딩합니다.

은 내가 currentTime을

완전히 거짓

로를 통과하기 전에 (W3C의 사양에 따라) 전체 두번째로 변환해야합니다. currentTimedouble으로 지정됩니다. 항상 시스템 시계의 시간과 동기화 재생 시간을 최신 키 프레임을 사용할 수 추구하거나 유지하기 위해 미디어 요소를 알 수있는 방법이있다 : https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-media-currenttime

내 질문은 이것이다?

마지막 버퍼가 자동으로 재생됩니다. 아무 것도 할 필요가 없습니다. 미디어 데이터가 버퍼에 있는지 확인하고 재생을 합리적인 수준으로 설정하여 작업을 수행하고 있습니다. 이 작업을 수행 할 수있는 네트워크 상태가 변경되면 항상 앞으로 나아갈 수 있지만 코드가 깨지고 버퍼링 전략이 깨진 것처럼 솔직하게 들릴 수 있습니다. 그렇지 않으면 재생이 간단 해집니다.

뒤에서 추락하면 자동으로 실행되지 않으며, 그래야합니다. 버퍼가 비워서 플레이어가 일시 중지 된 경우 재생을 다시 시작하려면 버퍼를 다시 빌드해야합니다. 그것이 버퍼의 전체 지점입니다.

또한 시스템 시계를 사용하여 시간에 제한을 두지 않으려는 것이 바람직하지 않으며 부당합니다. 장치마다 새로 고침 빈도가 다르고 비디오를 다른 속도로 처리합니다. 그냥 놀아서 연주하게하십시오. 몇 초 후에 끝나면 currentTime으로 설정하십시오.하지만 그렇게하기 전에 버퍼링 한 내용을 잘 알고 있어야합니다.

+0

문제가 발생했는지 알 수 없지만 예를 들어 2.7 초 패킷의 소켓이있는 노드에서 mp3 파일을 전송하면 플레이어가 정상적으로 시작되지만 수동으로 일시 중지하면 버퍼가 증가하기 시작합니다 그리고 다시 연주하면 멈춘 곳에서부터 시작됩니다. 이로 인해 재생이 nodej 스트림과 동기화되지 않습니다. 몇 시간 동안 재생을 허용하면 글리치로 인해 자동으로 일시 중지되고 버퍼가 증가하기 시작합니다. –

+0

nodejs는 2.7 초를 전송하고 재생을 기다린 후 다음 패킷을 보냅니다. 그러나 버퍼가 증가하면 스트리밍 된 데이터가 재생되었는지 여부를 더 이상 제어 할 수 없습니다. 패킷이 재생되었다는 것을 알려주는 "acknowledgment"를 보내려고했는데 다음 패킷이 배달 될 수 있지만 다른 문제가 발생했습니다. 재생 중지와 같습니다. 따라서 문제는 데이터를 스트리밍하여 연속적으로 몇 시간 동안 재생하도록하는 것입니다. –

+0

@KeyneViana 데이터의 다음 덩어리를 보내려면 왜 기다려야할까요? 계속 보내주세요. 또한, 2.7 초를 기다리지 말아야합니다 ... MP3 프레임은 576 샘플만큼 작을 수 있습니다. – Brad

관련 문제