0

ユーザーがビデオ メッセージを記録できる Web アプリを作成しようとしています。可能な限り最高の品質を取得しようとしています (アップロード時間が長くなる場合でも)。サーバーコードは次のようになり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");
                                });
    }
}
4

1 に答える 1

0

一般的な解像度を使用し、デフォルトの 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);

何が起こるかというと、現在 Web カメラから 800x480@24fps を要求しているということです。800x480@24fps は広くサポートされている解像度ではありません。つまり、ほとんどの Web カメラでは、Web カメラが応答するものは何でも得られます (これは最高の品質ではない可能性があります)。640 x 480 @ 30fps などの一般的な解像度を要求すると、ほとんどの Web カメラで確実にそれが得られます。

cam.setQuality(0, 90);

これcam.setQualityは、次のように変換されるデフォルト値を使用することを意味するコメントが付けられています:

130kbits/s は非常に低いです。cam.setQuality(0, 90)画質を 90 に維持するために必要なだけの帯域幅を使用するように Flash に指示するために使用します。

詳細については、 Camera.SetQualityのドキュメントを参照してください。

Red5 バージョン

Red5 を使用している場合は、少なくともRed5 1.0.3を使用していることを確認してください。ビデオ録画を修正した最初のバージョンです。以前のバージョンはすべて、ビデオ録画が壊れていました。詳細については、この質問を参照してください。

商用ソリューション

モバイルや .mp4 への変換を含むすべてを処理するHDFVRPipeなどの商用ソリューションの使用も検討する必要があります。

「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>
于 2015-11-01T13:08:11.210 に答える