Skip to content

Commit

Permalink
add stat info
Browse files Browse the repository at this point in the history
  • Loading branch information
kutu committed Jun 18, 2013
1 parent e196fa0 commit 3e60da6
Show file tree
Hide file tree
Showing 11 changed files with 598 additions and 0 deletions.
Binary file added assets/skin/close.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions locale/en_US/Main.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ initializing = initializing
liveLabel = Live
qualitiesAuto = Auto
subtitlesOff = Off
showStatInfo = Show statistics
1 change: 1 addition & 0 deletions locale/ru_RU/Main.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ initializing = инициализация
liveLabel = Прямой эфир
qualitiesAuto = Авто
subtitlesOff = Отключены
showStatInfo = Показать статистику
3 changes: 3 additions & 0 deletions src/ru/kutu/grindplayer/config/AppConfig.as
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ package ru.kutu.grindplayer.config {
import ru.kutu.grind.views.api.IQualityMenuButton;
import ru.kutu.grind.views.api.IScrubBar;
import ru.kutu.grind.views.api.IScrubBarTip;
import ru.kutu.grind.views.api.IStatInfo;
import ru.kutu.grind.views.api.ITimeInfo;
import ru.kutu.grind.views.api.IVolumeComponent;
import ru.kutu.grind.views.mediators.AlternateMenuBaseMediator;
Expand All @@ -52,6 +53,7 @@ package ru.kutu.grindplayer.config {
import ru.kutu.grindplayer.views.mediators.ScrubBarMediator;
import ru.kutu.grindplayer.views.mediators.ScrubBarMinimizedMediator;
import ru.kutu.grindplayer.views.mediators.ShortcutsMediator;
import ru.kutu.grindplayer.views.mediators.StatInfoMediator;
import ru.kutu.grindplayer.views.mediators.SubtitlesMediator;
import ru.kutu.grindplayer.views.mediators.SubtitlesMenuMediator;
import ru.kutu.grindplayer.views.mediators.api.IScrubBarMinimized;
Expand Down Expand Up @@ -82,6 +84,7 @@ package ru.kutu.grindplayer.config {
mediatorMap.map(Subtitles).toMediator(SubtitlesMediator);
mediatorMap.map(IControlBarView).toMediator(ControlBarBaseMediator);
mediatorMap.map(IBufferInfo).toMediator(BufferInfoMediator);
mediatorMap.map(IStatInfo).toMediator(StatInfoMediator);

mediatorMap.map(IScrubBar).toMediator(ScrubBarMediator);
mediatorMap.map(IScrubBarTip).toMediator(ScrubBarTipBaseMediator);
Expand Down
6 changes: 6 additions & 0 deletions src/ru/kutu/grindplayer/views/components/PlayerView.mxml
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,10 @@
horizontalCenter="0"
/>

<components:StatInfo
id="qosInfo"
left="4"
top="4"
/>

</s:Group>
271 changes: 271 additions & 0 deletions src/ru/kutu/grindplayer/views/components/StatInfo.mxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,271 @@
<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:renderers="ru.kutu.grindplayer.views.components.renderers.*"
mouseEnabled="false"
visible="false"
fontSize="10"
implements="ru.kutu.grind.views.api.IStatInfo"
>

<fx:Script>
<![CDATA[
import org.osmf.media.videoClasses.VideoSurface;
import org.osmf.media.videoClasses.VideoSurfaceInfo;
import org.osmf.net.qos.FragmentDetails;
import org.osmf.net.qos.QoSInfo;
import org.osmf.utils.OSMFSettings;
import ru.kutu.grind.events.StatInfoEvent;
private var prevDroppedFrames:int;
private var prevBytesLoaded:uint;
private var prevBytesLoadedTimestamp:int;
override public function set visible(value:Boolean):void {
super.visible = includeInLayout = value;
}
public function clear():void {
hardwareVideoDecoding.text = "";
hardwareVideoRendering.text = "";
frameRateChart.clear();
droppedFramesChart.clear();
bufferLengthChart.clear();
downloadSpeedChartHttp.clear();
downloadSpeedChart.clear();
memoryUsageChart.clear();
prevDroppedFrames = -1;
prevBytesLoaded = 0;
downloadSpeedGroup.visible = downloadSpeedGroup.includeInLayout = false;
downloadSpeedHttpGroup.visible = downloadSpeedHttpGroup.includeInLayout = false;
}
public function update(videoSurface:VideoSurface, netStream:NetStream, qosInfos:Vector.<QoSInfo>):void {
var mbps:Number;
if (videoSurface) {
const videoSurfaceInfo:VideoSurfaceInfo = videoSurface.info;
hardwareVideoDecoding.text = videoSurfaceInfo.renderStatus;
hardwareVideoRendering.text = OSMFSettings.supportsStageVideo
? videoSurfaceInfo.stageVideoInUse
? "accelerated (StageVideo " + videoSurfaceInfo.stageVideoInUseCount + "/" + videoSurfaceInfo.stageVideoCount + ")"
: "software"
: "unavailable";
}
if (netStream) {
var nsInfo:NetStreamInfo = netStream.info;
// frame rate
frameRate.text = Math.round(netStream.currentFPS).toString();
frameRateChart.addValue(netStream.currentFPS);
// dropped frames
if (nsInfo) {
if (prevDroppedFrames != -1) {
droppedFrames.text = Math.round(nsInfo.droppedFrames).toString();
droppedFramesChart.addValue(nsInfo.droppedFrames - prevDroppedFrames);
}
prevDroppedFrames = nsInfo.droppedFrames;
}
// buffer length/time
bufferLength.text = netStream.bufferLength.toFixed(1);
bufferTime.text = netStream.bufferTime.toFixed(1);
bufferLengthChart.addValue(netStream.bufferLength);
// download speed
if (netStream.bytesLoaded < netStream.bytesTotal) {
// progressive download
if (prevBytesLoaded > 0) {
mbps = (netStream.bytesLoaded - prevBytesLoaded) / ((getTimer() - prevBytesLoadedTimestamp) * .001);
}
prevBytesLoaded = netStream.bytesLoaded;
prevBytesLoadedTimestamp = getTimer();
} else if (nsInfo) {
// rtmp
mbps = nsInfo.dataBytesPerSecond + nsInfo.videoBytesPerSecond + nsInfo.audioBytesPerSecond;
if (!downloadSpeedGroup.visible && mbps == 0.0) mbps = NaN;
}
if (!isNaN(mbps)) {
if (!downloadSpeedGroup.visible) {
downloadSpeedGroup.visible = downloadSpeedGroup.includeInLayout = true;
}
mbps /= 125000;
downloadSpeed.text = mbps.toFixed(2);
downloadSpeedChart.addValue(mbps);
}
}
// download speed
if (qosInfos && qosInfos.length) {
// http streaming
if (!downloadSpeedHttpGroup.visible) {
downloadSpeedHttpGroup.visible = downloadSpeedHttpGroup.includeInLayout = true;
}
for each (var qosInfo:QoSInfo in qosInfos) {
var details:FragmentDetails = qosInfo.lastDownloadedFragmentDetails;
if (!details) continue;
if (details.downloadDuration < 0.5) {
// cache
downloadSpeedHttp.text = "cache";
downloadSpeedChartHttp.addValue(0.0);
} else {
mbps = details.size / details.downloadDuration / 125000;
downloadSpeedHttp.text = mbps.toFixed(2);
downloadSpeedChartHttp.addValue(mbps);
}
}
}
// memory usage
var memory:Number = System.totalMemoryNumber / 1048576;
memoryUsage.text = memory.toFixed(2);
memoryUsageChart.addValue(memory);
}
]]>
</fx:Script>

<fx:Style>
.minMaxGroup {
fontSize: 8;
}
.minValue {
alignmentBaseline: descent;
baselineShift: -1;
}
</fx:Style>

<s:Rect
left="0" right="0"
top="0" bottom="0"
>
<s:stroke>
<s:SolidColorStroke
color="0x666666"
/>
</s:stroke>
<s:fill>
<s:SolidColor
color="{getStyle('controlBarBackgroundColor')}"
alpha="{getStyle('controlBarBackgroundAlpha')}"
/>
</s:fill>
</s:Rect>

<s:Button
width="14"
height="14"
top="3"
right="3"
click="dispatchEvent(new StatInfoEvent(StatInfoEvent.HIDE))"
skinClass="ru.kutu.grindplayer.views.skins.CloseButtonSkin"
/>

<s:VGroup
minWidth="220"
mouseEnabled="false"
mouseChildren="false"
paddingLeft="5" paddingRight="5"
paddingTop="6" paddingBottom="6"
horizontalAlign="justify"
gap="6"
>

<s:HGroup gap="2">
<s:Label text="Video Decoding:" />
<s:Label id="hardwareVideoDecoding" />
</s:HGroup>

<s:HGroup gap="2">
<s:Label text="Video Rendering:" />
<s:Label id="hardwareVideoRendering" />
</s:HGroup>

<s:VGroup gap="1">
<s:Label text="Frame Rate" />

<s:HGroup width="100%" height="20" gap="0">
<s:Group height="100%" styleName="minMaxGroup">
<s:Label right="0" text="{frameRateChart.max.toFixed(1)}" />
<s:Label right="0" bottom="0" text="{frameRateChart.min.toFixed(1)}" styleName="minValue" />
</s:Group>
<renderers:StatChart id="frameRateChart" width="100%" height="100%" />
<s:Label id="frameRate" paddingLeft="1" />
</s:HGroup>
</s:VGroup>

<s:VGroup gap="1">
<s:Label text="Dropped Frames" />

<s:HGroup width="100%" height="100%" minHeight="16" gap="0">
<s:Label text="{droppedFramesChart.max}" styleName="minMaxGroup" />
<renderers:StatBarChart id="droppedFramesChart" width="100%" height="100%" barWidth="1" />
<s:Label id="droppedFrames" paddingLeft="2" />
</s:HGroup>
</s:VGroup>

<s:VGroup gap="1">
<s:Label text="Buffer Length, s" />

<s:HGroup width="100%" height="20" gap="0">
<s:Group height="100%" styleName="minMaxGroup">
<s:Label right="0" text="{bufferLengthChart.max.toFixed(1)}" />
<s:Label right="0" bottom="0" text="{bufferLengthChart.min.toFixed(1)}" styleName="minValue" />
</s:Group>
<renderers:StatChart id="bufferLengthChart" width="100%" height="100%" />
<s:VGroup gap="0" horizontalAlign="right" paddingLeft="1">
<s:Label id="bufferLength" />
<s:Label id="bufferTime" color="0x999999" />
</s:VGroup>
</s:HGroup>
</s:VGroup>

<!-- progressive, rtmp -->
<s:VGroup id="downloadSpeedGroup" gap="1">
<s:Label text="Download Speed, Mbps" />

<s:HGroup width="100%" height="20" gap="0">
<s:Group height="100%" styleName="minMaxGroup">
<s:Label right="0" text="{downloadSpeedChart.max.toFixed(1)}" />
<s:Label right="0" bottom="0" text="{downloadSpeedChart.min.toFixed(1)}" styleName="minValue" />
</s:Group>
<renderers:StatChart id="downloadSpeedChart" width="100%" height="100%" />
<s:Label id="downloadSpeed" paddingLeft="1" />
</s:HGroup>
</s:VGroup>

<!-- http streaming -->
<s:VGroup id="downloadSpeedHttpGroup" gap="1">
<s:Label text="Download Speed, Mbit/s" />

<s:HGroup width="100%" height="100%" minHeight="16" gap="0">
<s:Label text="{downloadSpeedChartHttp.max.toFixed(1)}" styleName="minMaxGroup" />
<renderers:StatBarChart id="downloadSpeedChartHttp" width="100%" height="100%" barWidth="3" />
<s:Label id="downloadSpeedHttp" paddingLeft="2" />
</s:HGroup>
</s:VGroup>

<s:VGroup gap="1">
<s:Label text="Memory usage, MB" />

<s:HGroup width="100%" height="20" gap="0">
<s:Group height="100%" styleName="minMaxGroup">
<s:Label right="0" text="{memoryUsageChart.max.toFixed(1)}" />
<s:Label right="0" bottom="0" text="{memoryUsageChart.min.toFixed(1)}" styleName="minValue" />
</s:Group>
<renderers:StatChart id="memoryUsageChart" width="100%" height="100%" />
<s:Label id="memoryUsage" paddingLeft="1" />
</s:HGroup>
</s:VGroup>

</s:VGroup>

</s:Group>
Loading

0 comments on commit 3e60da6

Please sign in to comment.