Синтаксис VLC для перекодирования и потока в stdout?

цель: я пытаюсь использовать в VLC как локальный сервер для расширения возможностей приложения, созданные с Adobe AIR, Flex и Actionscript. Я использую VLC для потока stdoutи чтение этого вывода из моего приложения.

возможности потоковой передачи VLC
VLC Flash Video
поток VLC на веб-сайт с asf и Flash

статус: I я могу запустить VLC в качестве фонового процесса и контролировать его через его пульт дистанционного управления интерфейс (более подробно). Я могу загружать, перекодировать и передавать локальный видеофайл. Пример приложения ниже-тестовый стенд barebones, демонстрирующий это.

вопрос: я получаю данные в мое приложение, но это не рендеринг видео. Я не знаю, является ли это проблемой с моими командами VLC или с записью / чтением из stdout. Эта техника чтение stdout в воздухе работает (с ffmpeg например).

одна из различных команд транскодирования, которые я пробовал:

-I rc  // remote control interface  
-vvv   // verbose debuging  
--sout  // transcode, stream to stdout 
"#transcode{vcodec=FLV1}:std{access=file,mux=ffmpeg{mux=flv},dst=-}"

это приводит к тому, что данные поступают в мое приложение, но по какой-то причине это не рендеринг как видео при использовании appendBytes С NetStream экземпляра.

если вместо этого я пишу данные .flv-файл, создается допустимый файл - поэтому сломанная часть, похоже, записывает его в stdout. одна вещь, которую я заметил: я не получать метаданные через stdout'Method. Если я воспроизвожу файл, созданный с помощью команды ниже, я вижу метаданные.

// writing to a file
var output:File = File.desktopDirectory.resolvePath("stream.flv");
var outputPath:String = output.nativePath;
"#transcode{vcodec=FLV1}:std{access=file,mux=ffmpeg{mux=flv},dst=" + outputPath + "}");

надеюсь, кто-то видит, где я ошибаюсь.


обновление 1: просто чтобы добавить некоторые детали (!- Я взглянул на него .flv-файл, созданный для проверки метаданных. Он отображается в начале файла, как показано ниже. У меня есть правильный onMetaData обработчик и следа эти данные, если я играю файл с диска. я не вижу этого следа при чтении из stdout и NetStream находится в Data Generation режим. возможно ли, что он не отправляется в stdout почему? Я попытался создать свой собственный заголовок и добавить его до начала потока – у меня может быть неправильный формат заголовка.

enter image description here


обновление 2: так по-моему AIR app я смог грубо разобрать входящий stdout поток, поступающий от VLC. Я хотел посмотреть, отправляются ли данные заголовка FLV – и похоже, что это так. Я не знаю, в правильном ли формате и т. д. но, как я уже упоминал выше, если я напишу an .flv файл вместо stdout, действительным .создал файл flv.

полностью в недоумении - попробовал все, что я мог придумать, и проследил за каждой веб-ссылкой, которую я мог найти по связанным с этим вопросам. Увы-так близко, и было бы так здорово использовать VLC внутри AIR.

2 ответов


в комментариях к другому вопросу вы спросили мои мысли:

я заметил, что в вашем коде вы используете процесс VLC в среде OSX.
На ПК с Windows имейте в виду, что -I rc позже не отвечает на standardInput отправлено команд. Я пользователь Windows, поэтому не могу помочь с этой частью.

попытался с помощью --no-rc-fake-tty или даже --rc-fake-tty, VLC все еще не ответил на stdout на ПК.

вы хотите сделать воспроизведение и поиск в VLC, но смотреть результат в AS3 (как проекционный экран), верно? но я даже не уверен, что VLC вернет вам теги FLV, начиная с выбранных временных меток и т. д. (ища, что вы получаете доступ к тегу FLV определенной временной метки и связанных данных a/v)...

другие игроки с питанием от FFmpeg/Mencoder, такие как MPlayer, я тестировал только отправку текстовых данных "статус" в stdout во время воспроизведения (поэтому не может быть подан в NetStream декодер для дисплея).

я смог грубо разобрать входящий stdout поток, поступающий от В VLC. Я хотел посмотреть, отправляются ли данные заголовка FLV – и это похоже, что так. Я не знаю, в правильном ли формате и т. д.

Проверьте байты: (допустимый заголовок FLV начинается с 46 4C 56 01 05 00 00 00 09 00 00 00 00)

просто обновите свой вопрос с помощью копирования-вставки результата "проверка байтов" из приведенной ниже функции. Тогда легче сказать вам, если он воспроизводится или, возможно, вам нужна альтернатива.

1) Настройки некоторые государственные (или частные) Вары...

  • сделать public var temp_String : String = "";
  • сделать public var videoStream:ByteArray = new ByteArray();

2) заменить функцию onOutputData С ниже код...

public function onOutputData(event:ProgressEvent):void 
{ 
    if (process && process.running)
    {
        if (process.standardOutput.bytesAvailable)
        {
            //# make a private/public bytearray outside of this function 
            //var videoStream:ByteArray = new ByteArray();

            process.standardOutput.readBytes(videoStream, videoStream.length, process.standardOutput.bytesAvailable);

            dataIn = process.standardOutput.bytesAvailable; 
            dataTotal += dataIn;
            //report.text = String("Current Bytes: " + dataIn + "\t Total Bytes: "+ dataTotal);

            if (videoStream.length >= 1000 )
            {
                //ns.appendBytes(videoStream);

                temp_String = bytes_toString(videoStream);
                trace("bytes checking : " + "\n");
                trace( temp_String ); //see hex of FLV bytes

                //# temporary pausing of progress events 
                process.removeEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
            }
            //trace(ns.info);
        }
    }
}

поддерживает функцию bytes_toString код :

public function bytes_toString ( ba:ByteArray ) : String
{
    var str_Hex:String = "";    var len:uint = ba.length;

    ba.position = 0;

    for (var i:uint = 0; i < len; i++) 
    {
        var n:String=ba.readUnsignedByte().toString(16); 

        if(n.length<2) //padding
        { n="0"+n; }    str_Hex += n ;
    }

    return str_Hex.toUpperCase();
}

некоторые другие Примечания :

каждый запуск событий прогресса захватывает только 32KB / 64kb пакеты входящих stdout байт за раз.

вы делаете свой videoStream:ByteArray = new ByteArray(); за пределами progressEvent, чтобы каждый запуск события не создавал новый byteArray (который отбрасывает старые данные, которые могут потребоваться позже для полного тега FLV).

не записывайте каждый пакет в 0 позиция, так как это перезапишет существующие данные. Добавить в конец существующего с помощью videoStream.length как новая позиция записи.

process.standardOutput.readBytes(videoStream, videoStream.length, process.standardOutput.bytesAvailable);

и if (videoStream.length){ ns.appendBytes(videoStream); } - это довольно опасно. Любые неполные данные (заголовка, фрейма или чего-либо еще) будут глушить декодер NetStream, если вы добавите слишком рано. Он не перезапустится, если вы не сбросите все и не начнете снова (повторно добавьте байты полного заголовка FLV, полный тег кадра и т. д.).


пару вещей, которые я бы попробовал, некоторые из которых вы, возможно, уже подумали:

  1. попробуйте без отладки включен, в случае, если это загрязняет ваш поток stdout.
  2. попробуйте другой формат видео (не FLV) в случае, если это проблема конкретного формата. Например, вы можете попробовать mpeg4
  3. попробуйте подключить поток stdout к чему-то еще, например ffplay, чтобы узнать, является ли проблема потоком или предположениями вашего принимающего приложения о поток.