mod_flvx - модуль апача для огранизации псевдо стриминга.
Сам его не устанавливал (делалось руками коллег), но если будут просьбы в фидбэк – напишу мануал по установке и настройке.
С меня требовался простенький плэер на ActionScript, как собственно и видно из названия заметки.
Все контрольки для управления воспроизведением были написаны на javascript, поэтому все основные функции воспроизведения выведены через ExternalInterface «во вне».
Собственно «меньше слов, больше кода!»:
package
{
import flash.display.*;
import flash.events.*;
import flash.net.*;
import flash.media.*;
import flash.utils.*;
import flash.external.ExternalInterface;
/**
* ...
* @author digitorum
*/
public class SimplePlayer extends Sprite
{
// инстас Video
private var video:Video;
// инстас NetConnection
private var netConnection:NetConnection;
// инстас NetStream
private var netStream:NetStream;
// урл до флв файла
private var flvUrl:String;
// ключевые кадры
private var keyFrames:Object = { };
// дилинна видео
private var videoDuration:Number = 0;
// готово ли видео к воспроизведению
private var isVideoReady:Boolean = false;
/*
* Конструктор, тут все как обычно
*/
public function SimplePlayer():void {
if (stage) {
_initPlayer();
} else {
addEventListener(Event.ADDED_TO_STAGE, _initPlayer);
}
}
/*
* Инициализация плеера
*/
private function _initPlayer(e:Event = null):void {
flvUrl = this.loaderInfo.parameters["flvVideo"] ? this.loaderInfo.parameters["flvVideo"] : '';
if (flvUrl == '') {
return;
}
netConnection = new NetConnection();
netConnection.connect(null);
netStream = new NetStream(netConnection);
netStream.bufferTime = 0;
netStream.maxPauseBufferTime = 0;
netStream.client = {
onMetaData : function(metaDataObj:Object):void {
videoDuration = metaDataObj.duration;
keyFrames = metaDataObj.keyframes;
isVideoReady = true;
return;
}
};
video = new Video(320, 240);
video.attachNetStream(netStream);
video.smoothing = true;
netStream.play(flvUrl);
external_pause();
stage.addChild(video);
if (ExternalInterface.available) {
ExternalInterface.addCallback('SimplePlayer_play', external_play);
ExternalInterface.addCallback('SimplePlayer_pause', external_pause);
ExternalInterface.addCallback('SimplePlayer_seek', external_seek);
ExternalInterface.addCallback('SimplePlayer_isReady', external_isReady);
ExternalInterface.addCallback('SimplePlayer_getVideoDuration', external_getVideoDuration);
ExternalInterface.addCallback('SimplePlayer_getCurrentPlayTime', external_getCurrentPlayTime);
ExternalInterface.addCallback('SimplePlayer_setVolume', external_setVolume);
}
}
/*
* Текущее время воспроизведения
*/
private function external_getCurrentPlayTime():Number {
return int(netStream.time);
}
/*
* Начать воспроизведение
*/
private function external_play():void {
netStream.resume();
}
/*
* Приостановить воспроизведение
*/
private function external_pause():void {
netStream.pause();
}
/*
* Проверить степень готовности плеера
*/
private function external_isReady():Boolean {
return isVideoReady;
}
/*
* Получить длинну видео в секундах
*/
private function external_getVideoDuration():Number {
return videoDuration;
}
/*
* Перемеотка видео
*/
private function external_seek(seconds:Number):void {
var i:Number;
for (i = 0; i < keyFrames.times.length; i++) {
if (keyFrames.times[i] >= seconds) {
netStream.play(flvUrl + '?start=' + keyFrames.filepositions[i]);
return;
}
}
}
/*
* громкость звука
*/
private function external_setVolume(index:Number):void {
var soundTransform:SoundTransform = netStream.soundTransform;
soundTransform.volume = index;
netStream.soundTransform = soundTransform;
}
}
}
В метаданных видеофайла должны присутствовать сведения о ключевых кадрах.
Как сконвертировать и подготовить видео я писал в другой
заметке. Главное только не путайте key frame и
cuePoint.
Для того, чтобы обновить в метаданных инфоромацию о ключевых кадрах, достаточно запустить flvtool2 с такими параметрами:
flvtool2 -U filename.flv