簡體   English   中英

使用Flash Media Server錄制網絡攝像頭

[英]Recording webcam with flash media server

我正在嘗試制作一個允許用戶錄制視頻消息的Web應用程序。 我正在嘗試獲得最好的質量(即使這意味着較長的上傳時間)。 我設法通過ns.publish("livestream", "live");進行錄音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");
                                });
    }
}

使用通用分辨率,避免使用默認setQuality值

您應該首先進行以​​下更改:

  1. 使用普通分辨率,例如640x480,幀頻為30
  2. 避免使用默認的cam.setQuality設置,並使用cam.setQuality(0,90)

以上翻譯為以下客戶端AS3代碼:

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

cam.setMode(640,480,24);

發生的情況是您當前正在從網絡攝像頭請求800x480 @ 24fps。 800x480 @ 24fps並非廣泛支持的分辨率,這意味着在大多數網絡攝像頭中,您將獲得網絡攝像頭響應的所有內容(這可能不是最佳質量)。 要求使用640 x 480 @ 30fps之類的通用分辨率,可以確保您在大多數網絡攝像頭上都能得到滿意的分辨率。

cam.setQuality(0, 90);

cam.setQuality進行了注釋,這意味着它將使用默認值轉換為:更改圖片質量,以將比特率保持在130kbits / s(或16384bytes / second)以下。

130kbits / s非常低。 使用cam.setQuality(0, 90)告訴Flash使用所需的帶寬以將圖片質量保持在90。

有關更多信息,請參見Camera.SetQuality文檔。

Red5版本

如果使用Red5,則應確保至少使用Red5 1.0.3 這是固定視頻錄制的第一個版本。 所有以前的版本都中斷了視頻錄制,有關詳細信息,請參閱此問題

商業解決方案

您還應該考慮使用諸如HDFVRPipe之類的商業解決方案,該解決方案可以處理包括移動設備和轉換為.mp4在內的所有內容。

關於“ 2個文件”的觀察

但是它在服務器上制作了2個文件並且質量沒有提高

根據您使用的媒體服務器,您可能會獲得1個,2個或更多文件。

例如, Red5將在錄制過程中創建另外兩個文件(.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>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM