Запись с веб-камеры с помощью сервера flash media

Я пытаюсь создать веб-приложение, которое позволяет пользователю записывать видео-сообщение. Я пытаюсь получить максимально возможное качество (даже если это означает долгую загрузку). Мне удается заставить запись работать с ns.publish("livestream", "live"); Код сервера выглядит так:

Client.prototype.startRecord = function( source, destination ) {
        trace("recording Stream: " + source + " to: " + destination);
        this.newStream = Stream.get(destination);
        this.fileRecording = destination;
        trace(this.fileRecording);

        if (this.newStream)
        {
            this.newStream.onStatus = function (info) {
                //trace(info.code );
                if (info.code == "NetStream.Play.PublishNotify") {              
                    trace("start recording");
                    this.record();
                }   
            }

            this.newStream.play(source)

        }
    }

    Client.prototype.stopRecord = function() {
        trace("stopping Recording");
        this.newStream.record(false);
        this.newStream.play(false);
    }

    Client.prototype.getFiles = function() {
        var fileRecord = new File("/streams/_definst_/"+this.fileRecording+".flv");

        if (fileRecord.exists)
        {
            return this.fileRecording;
        }

        return "error recording";
    }


    application.onConnect = function(clObj) {
        this.acceptConnection(clObj);
    }

Проблема в том, что качество невысокое. Я пробовал использовать ns.publish("livestream", "record");, но он создает 2 файла на сервере, и качество не улучшается, есть предложения? Я также могу загрузить клиентский код, если он вам нужен.

Код клиента:

import flash.media.*;
import flash.events.*;
import flash.net.*;
import flash.utils.getTimer;

var vid:Video;
var mic:Microphone;
var cam:Camera;
var fileListObj:Object = {};
var ns:NetStream;
var nc:NetConnection;
var recordingName:String;

initCamera();

function initCamera ():void
{
    if (Camera.isSupported)
    {
        cam = Camera.getCamera();

        cam.setMode (800, 480, 24);
        //cam.setQuality(0, 90);
        vid = new Video(cam.width,cam.height);

        vid.attachCamera (cam);

        if (Microphone.isSupported)
        {
            mic = Microphone.getEnhancedMicrophone();       
        }

        this.addChildAt (vid, 1);

        vid.x = (800 - vid.width) >> 1;
        vid.y = (480 - vid.height) >> 1;        

        initConnection();
    }
    else
    {
        trace ("no camera");
    }
}


function initConnection ():void
{
    nc = new NetConnection();

    nc.addEventListener (NetStatusEvent.NET_STATUS, netStatusHandler);
    nc.addEventListener (AsyncErrorEvent.ASYNC_ERROR, function (event:AsyncErrorEvent):void {trace("error");});

    nc.connect ("rtmp://adrian7.srfms.com/nabCapture");
}



function recordVideo (event:MouseEvent):void
{
    if (record_mc.label == "Record")
    {
        record_mc.label = "Stop Record";

        var currentTime:Date = new Date();

        recordingName = "myRecording"+getTimer()+""+currentTime.time;

        nc.call ("startRecord", new Responder(startPublish), "livestream", recordingName);


    }
    else
    {
        record_mc.enabled = false;
        record_mc.label = "Record";

        nc.call ("stopRecord", null);
        ns.close();

        nc.call ("getFiles", new Responder(onResultFileListObj, null));     
    }
}

function startPublish (result:Object):void
{
    ns.publish("livestream", "live");
}

function netStatusHandler (event:NetStatusEvent):void
{
    //trace (event.info.code);
    if (event.info.code == "NetConnection.Connect.Success")
    {
        ns = new NetStream(nc);

        ns.attachCamera (cam);
        if (mic)
        {
            ns.attachAudio(mic);
        }

        record_mc.enabled = true;
        record_mc.addEventListener (MouseEvent.CLICK, recordVideo);
    }
}



function onResultFileListObj (resultObj:Object):void 
{
    if (String(resultObj) != "error recording")
    {
        recordingName = String(resultObj);

        see_mc.enabled = true;
        see_mc.addEventListener(MouseEvent.CLICK, function (event:MouseEvent):void {
                        navigateToURL(new URLRequest("http://www.labs.adrian281990.com/fms_demo1/index.php?id=" + recordingName), "_self");
                                });
    }
}

person user1500639    schedule 04.07.2012    source источник
comment
Да, покажите код клиента. Клиент может настроить разрешение захвата веб-камеры с помощью Camera.setMode () и установите некоторые предпочтения для качества изображения или потребления полосы пропускания с помощью Camera.setQuality ()   -  person Sunil D.    schedule 04.07.2012
comment
cam = Camera.getCamera (); cam.setMode (800, 480, 24); //cam.setQuality(0, 90); vid = новое видео (cam.width, cam.height); vid.attachCamera (камера); если (Microphone.isSupported) {mic = Microphone.getEnhancedMicrophone (); }   -  person user1500639    schedule 04.07.2012
comment
Видео (и разрешения, поддерживаемые веб-камерами) обычно имеют соотношение 4: 3. Веб-камера, вероятно, не поддерживает 800x480, поэтому Flash пытается найти что-то близкое. Результат может быть не таким хорошим. Попробуйте использовать другие значения: 800x600, 640x480, 480x360 или другие значения с соотношением сторон 4: 3. Если конечный результат должен быть другого размера, вы можете масштабировать или обрезать видео (с некоторыми усилиями). Я получаю отличные результаты при разрешении 480x360.   -  person Sunil D.    schedule 07.07.2012


Ответы (1)


Используйте обычное разрешение и избегайте значений setQuality по умолчанию

Вам следует начать с внесения следующих изменений:

  1. Используйте обычное разрешение, например 640 x 480, и частоту кадров 30.
  2. Избегайте настроек по умолчанию cam.setQuality и используйте cam.setQuality(0,90)

приведенное выше переводится в следующий клиентский код AS3:

cam.setMode (640, 480, 24);
cam.setQuality(0, 90);

cam.setMode(640,480,24);

Что происходит, так это то, что вы сейчас запрашиваете с веб-камеры 800x480 @ 24 кадра в секунду. Разрешение 800x480 @ 24fps не является широко поддерживаемым, что означает, что на большинстве веб-камер вы получите то, что веб-камера реагирует (что может быть не самого лучшего качества). Запрос на обычное разрешение, например 640 x 480 при 30 кадрах в секунду, гарантирует, что вы получите именно это на большинстве веб-камер.

cam.setQuality(0, 90);

Ваш cam.setQuality прокомментирован, что означает, что он будет использовать значения по умолчанию, что означает: изменять качество изображения, чтобы битрейт не превышал 130 кбит / с (или 16384 байта / секунду).

130 кбит / с ОЧЕНЬ НИЗКО. Используйте cam.setQuality(0, 90), чтобы Flash использовал столько полосы пропускания, сколько необходимо для сохранения качества изображения на уровне 90.

См. Документацию Camera.SetQuality для больше информации.

Версия Red5

Если вы используете Red5, убедитесь, что вы используете как минимум Red5 1.0.3. Это первая версия с исправленной записью видео. Во всех предыдущих версиях запись видео была прервана, см. этот вопрос для подробностей.

Коммерческие решения

Вам также следует рассмотреть возможность использования коммерческого решения, такого как HDFVR или Pipe, которые обрабатывают все, включая мобильные устройства и преобразование в .mp4.

Относительно вашего наблюдения "2 файла"

но он делает 2 файла на сервере, и качество не улучшается

В зависимости от используемого вами медиа-сервера вы можете получить 1, 2 или более файлов.

Например, Red5 создаст 2 других файла в процессе записи (.ser и .info):

введите описание изображения здесь

и после первого воспроизведения он создаст еще один файл .meta, содержащий список ключевых кадров, их положение в байтах и ​​временную метку:

введите описание изображения здесь

Вот содержимое такого .meta файла:

<?xml version="1.0" encoding="UTF-8"?>
<FrameMetadata audioOnly="false" duration="24074" modified="1446217872000">
    <KeyFrame position="566" timestamp="39"/>
    <KeyFrame position="626" timestamp="40"/>
    <KeyFrame position="14705" timestamp="574"/>
    <KeyFrame position="14765" timestamp="575"/>
    ...
</FrameMetadata>
person Remus Negrota    schedule 01.11.2015