nginx-mod-rtmp/doc/rtmp.py

858 lines
639 KiB
Python
Raw Normal View History

2012-05-03 00:28:21 +02:00
<!DOCTYPE html>
<!-- saved from url=(0061)http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="ROBOTS" content="NOARCHIVE">
<link rel="icon" type="image/vnd.microsoft.icon" href="http://www.gstatic.com/codesite/ph/images/phosting.ico">
<script src="./rtmp_files/cb=gapi.loaded0" async=""></script><script type="text/javascript" async="" src="./rtmp_files/plusone.js" gapi_processed="true"></script><script type="text/javascript">
var codesite_token = "vVg-YEkpsP38PydkCFlVS-ioMOA:1335711600965";
var CS_env = {"profileUrl":["/u/102069584091941751068/"],"token":"vVg-YEkpsP38PydkCFlVS-ioMOA:1335711600965","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"assetVersionPath":"http://www.gstatic.com/codesite/ph/12151595242108277468","projectHomeUrl":"/p/rtmplite","relativeBaseUrl":"","projectName":"rtmplite","loggedInUserEmail":"arutyunyan.roman@gmail.com"};
var _gaq = _gaq || [];
_gaq.push(
['siteTracker._setAccount', 'UA-18071-1'],
['siteTracker._trackPageview']);
</script>
<title>rtmp.py -
rtmplite -
Flash RTMP server in Python - Google Project Hosting
</title>
<link type="text/css" rel="stylesheet" href="./rtmp_files/core.css">
<link type="text/css" rel="stylesheet" href="./rtmp_files/ph_detail.css">
<link type="text/css" rel="stylesheet" href="./rtmp_files/d_sb.css">
<!--[if IE]>
<link type="text/css" rel="stylesheet" href="http://www.gstatic.com/codesite/ph/12151595242108277468/css/d_ie.css" >
<![endif]-->
<style type="text/css">
.menuIcon.off { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -42px }
.menuIcon.on { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 -28px }
.menuIcon.down { background: no-repeat url(http://www.gstatic.com/codesite/ph/images/dropdown_sprite.gif) 0 0; }
tr.inline_comment {
background: #fff;
vertical-align: top;
}
div.draft, div.published {
padding: .3em;
border: 1px solid #999;
margin-bottom: .1em;
font-family: arial, sans-serif;
max-width: 60em;
}
div.draft {
background: #ffa;
}
div.published {
background: #e5ecf9;
}
div.published .body, div.draft .body {
padding: .5em .1em .1em .1em;
max-width: 60em;
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
white-space: -o-pre-wrap;
word-wrap: break-word;
font-size: 1em;
}
div.draft .actions {
margin-left: 1em;
font-size: 90%;
}
div.draft form {
padding: .5em .5em .5em 0;
}
div.draft textarea, div.published textarea {
width: 95%;
height: 10em;
font-family: arial, sans-serif;
margin-bottom: .5em;
}
.nocursor, .nocursor td, .cursor_hidden, .cursor_hidden td {
background-color: white;
height: 2px;
}
.cursor, .cursor td {
background-color: darkblue;
height: 2px;
display: '';
}
.list {
border: 1px solid white;
border-bottom: 0;
}
</style>
<script type="text/javascript" async="" src="./rtmp_files/ga.js"></script></head>
<body class="t4">
<script type="text/javascript">
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(ga);
})();
</script>
<script type="text/javascript">
window.___gcfg = {lang: 'en'};
(function()
{var po = document.createElement("script");
po.type = "text/javascript"; po.async = true;po.src = "https://apis.google.com/js/plusone.js";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(po, s);
})();
</script>
<div class="headbg">
<div id="gaia">
<span>
<b>arutyunyan.roman@gmail.com</b>
| <a href="http://code.google.com/u/102069584091941751068/" id="projects-dropdown" onclick="return false;"><u>My favorites</u> <small></small></a>
| <a href="http://code.google.com/u/102069584091941751068/" onclick="_CS_click(&#39;/gb/ph/profile&#39;);" title="Profile, Updates, and Settings"><u>Profile</u></a>
| <a href="https://www.google.com/accounts/Logout?continue=http%3A%2F%2Fcode.google.com%2Fp%2Frtmplite%2Fsource%2Fbrowse%2Ftrunk%2Frtmp.py" onclick="_CS_click(&#39;/gb/ph/signout&#39;);"><u>Sign out</u></a>
</span>
</div>
<div class="gbh" style="left: 0pt;"></div>
<div class="gbh" style="right: 0pt;"></div>
<div style="height: 1px"></div>
<!--[if lte IE 7]>
<div style="text-align:center;">
Your version of Internet Explorer is not supported. Try a browser that
contributes to open source, such as <a href="http://www.firefox.com">Firefox</a>,
<a href="http://www.google.com/chrome">Google Chrome</a>, or
<a href="http://code.google.com/chrome/chromeframe/">Google Chrome Frame</a>.
</div>
<![endif]-->
<table style="padding:0px; margin: 0px 0px 10px 0px; width:100%" cellpadding="0" cellspacing="0" itemscope="" itemtype="http://schema.org/CreativeWork">
<tbody><tr style="height: 58px;">
<td id="plogo">
<link itemprop="url" href="http://code.google.com/p/rtmplite">
<a href="http://code.google.com/p/rtmplite/">
<img src="./rtmp_files/logo" alt="Logo" itemprop="image">
</a>
</td>
<td style="padding-left: 0.5em">
<div id="pname">
<a href="http://code.google.com/p/rtmplite/"><span itemprop="name">rtmplite</span></a>
</div>
<div id="psum">
<a id="project_summary_link" href="http://code.google.com/p/rtmplite/"><span itemprop="description">Flash RTMP server in Python</span></a>
</div>
</td>
<td style="white-space:nowrap;text-align:right; vertical-align:bottom;">
<form action="http://code.google.com/hosting/search">
<input size="30" name="q" value="" type="text">
<input type="submit" name="projectsearch" value="Search projects">
</form>
</td></tr>
</tbody></table>
</div>
<div id="mt" class="gtb">
<a href="http://code.google.com/p/rtmplite/" class="tab ">Project&nbsp;Home</a>
<a href="http://code.google.com/p/rtmplite/downloads/list" class="tab ">Downloads</a>
<a href="http://code.google.com/p/rtmplite/w/list" class="tab ">Wiki</a>
<a href="http://code.google.com/p/rtmplite/issues/list" class="tab ">Issues</a>
<a href="http://code.google.com/p/rtmplite/source/checkout" class="tab active">Source</a>
<div class="gtbc"></div>
</div>
<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0" class="st">
<tbody><tr>
<td class="subt">
<div class="st2">
<div class="isf">
<span class="inst1"><a href="http://code.google.com/p/rtmplite/source/checkout">Checkout</a></span> &nbsp;
<span class="inst2"><a href="http://code.google.com/p/rtmplite/source/browse/trunk">Browse</a></span> &nbsp;
<span class="inst3"><a href="http://code.google.com/p/rtmplite/source/list">Changes</a></span> &nbsp;
&nbsp;
<form action="http://code.google.com/p/rtmplite/source/search" method="get" style="display:inline" onsubmit="document.getElementById(&#39;codesearchq&#39;).value = document.getElementById(&#39;origq&#39;).value">
<input type="hidden" name="q" id="codesearchq" value="">
<input type="text" maxlength="2048" size="38" id="origq" name="origq" value="" title="Google Code Search" style="font-size:92%">&nbsp;<input type="submit" value="Search Trunk" name="btnG" style="font-size:92%">
</form>
</div>
</div>
</td>
<td align="right" valign="top" class="bevel-right"></td>
</tr>
</tbody></table>
<script type="text/javascript">
var cancelBubble = false;
function _go(url) { document.location = url; }
</script>
<div id="maincol">
<!-- IE -->
<div class="expand">
<div id="colcontrol">
<style type="text/css">
#file_flipper { white-space: nowrap; padding-right: 2em; }
#file_flipper.hidden { display: none; }
#file_flipper .pagelink { color: #0000CC; text-decoration: underline; }
#file_flipper #visiblefiles { padding-left: 0.5em; padding-right: 0.5em; }
</style>
<table id="nav_and_rev" class="list" cellpadding="0" cellspacing="0" width="100%">
<tbody><tr>
<td nowrap="nowrap" class="src_crumbs src_nav" width="33%">
<strong class="src_nav">Source path:&nbsp;</strong>
<span id="crumb_root">
<a href="http://code.google.com/p/rtmplite/source/browse/">svn</a>/&nbsp;</span>
<span id="crumb_links" class="ifClosed"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/">trunk</a><span class="sp">/&nbsp;</span>rtmp.py</span>
</td>
<td nowrap="nowrap" width="33%" align="center">
<a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py?edit=1"><img src="./rtmp_files/pencil-y14.png" class="edit_icon">Edit file</a>
</td>
<td nowrap="nowrap" width="33%" align="right">
<table cellpadding="0" cellspacing="0" style="font-size: 100%"><tbody><tr>
<td class="flipper">
<ul class="leftside">
<li><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py?r=142" title="Previous">r142</a></li>
</ul>
</td>
<td class="flipper"><b>r154</b></td>
</tr></tbody></table>
</td>
</tr>
</tbody></table>
<div class="fc">
<style type="text/css">
.undermouse span {
background-image: url(http://www.gstatic.com/codesite/ph/images/comments.gif); }
</style>
<table class="opened" id="review_comment_area"><tbody><tr>
<td id="nums">
<pre><table width="100%"><tbody><tr class="nocursor"><td></td></tr></tbody></table></pre>
<pre><table width="100%" id="nums_table_0"><tbody><tr id="gr_svn154_1"><td id="1"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#1">1</a></td></tr><tr id="gr_svn154_2"><td id="2"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#2">2</a></td></tr><tr id="gr_svn154_3"><td id="3"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#3">3</a></td></tr><tr id="gr_svn154_4"><td id="4"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#4">4</a></td></tr><tr id="gr_svn154_5"><td id="5"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#5">5</a></td></tr><tr id="gr_svn154_6"><td id="6"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#6">6</a></td></tr><tr id="gr_svn154_7"><td id="7"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#7">7</a></td></tr><tr id="gr_svn154_8"><td id="8"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#8">8</a></td></tr><tr id="gr_svn154_9"><td id="9"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#9">9</a></td></tr><tr id="gr_svn154_10"><td id="10"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#10">10</a></td></tr><tr id="gr_svn154_11"><td id="11"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#11">11</a></td></tr><tr id="gr_svn154_12"><td id="12"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#12">12</a></td></tr><tr id="gr_svn154_13"><td id="13"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#13">13</a></td></tr><tr id="gr_svn154_14"><td id="14"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#14">14</a></td></tr><tr id="gr_svn154_15"><td id="15"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#15">15</a></td></tr><tr id="gr_svn154_16"><td id="16"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#16">16</a></td></tr><tr id="gr_svn154_17"><td id="17"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#17">17</a></td></tr><tr id="gr_svn154_18"><td id="18"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#18">18</a></td></tr><tr id="gr_svn154_19"><td id="19"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#19">19</a></td></tr><tr id="gr_svn154_20"><td id="20"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#20">20</a></td></tr><tr id="gr_svn154_21"><td id="21"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#21">21</a></td></tr><tr id="gr_svn154_22"><td id="22"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#22">22</a></td></tr><tr id="gr_svn154_23"><td id="23"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#23">23</a></td></tr><tr id="gr_svn154_24"><td id="24"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#24">24</a></td></tr><tr id="gr_svn154_25"><td id="25"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#25">25</a></td></tr><tr id="gr_svn154_26"><td id="26"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#26">26</a></td></tr><tr id="gr_svn154_27"><td id="27"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#27">27</a></td></tr><tr id="gr_svn154_28"><td id="28"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#28">28</a></td></tr><tr id="gr_svn154_29"><td id="29"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#29">29</a></td></tr><tr id="gr_svn154_30"><td id="30"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#30">30</a></td></tr><tr id="gr_svn154_31"><td id="31"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#31">31</a></td></tr><tr id="gr_svn154_32"><td id="32"><a href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#32">32</a></td></tr><tr id="gr_svn154_33"><td id="33"><a href="http://code.google.com/p/rtmplite/sour
<pre><table width="100%"><tbody><tr class="nocursor"><td></td></tr></tbody></table></pre>
</td>
<td id="lines">
<pre><table width="100%"><tbody><tr class="cursor_stop cursor_hidden"><td></td></tr></tbody></table></pre>
<pre class="prettyprint lang-py"><table id="src_table_0"><tbody><tr id="sl_svn154_1"><td class="source"><span class="com"># Copyright (c) 2007-2009, Mamta Singh. All rights reserved. see README for details.</span><span class="pln"><br></span></td></tr><tr id="sl_svn154_2"><td class="source"><span class="com"># Copyright (c) 2010-2011, Kundan Singh.</span><span class="pln"><br></span></td></tr><tr id="sl_svn154_3"><td class="source"><span class="pln"><br></span></td></tr><tr id="sl_svn154_4"><td class="source"><span class="str">'''<br></span></td></tr><tr id="sl_svn154_5"><td class="source"><span class="str">This is a simple implementation of a Flash RTMP server to accept connections and stream requests. The module is organized as follows:<br></span></td></tr><tr id="sl_svn154_6"><td class="source"><span class="str">1. The FlashServer class is the main class to provide the server abstraction. It uses the multitask module for co-operative multitasking.<br></span></td></tr><tr id="sl_svn154_7"><td class="source"><span class="str">&nbsp; &nbsp;It also uses the App abstract class to implement the applications.<br></span></td></tr><tr id="sl_svn154_8"><td class="source"><span class="str">2. The Server class implements a simple server to receive new Client connections and inform the FlashServer application. The Client class<br></span></td></tr><tr id="sl_svn154_9"><td class="source"><span class="str">&nbsp; &nbsp;derived from Protocol implements the RTMP client functions. The Protocol class implements the base RTMP protocol parsing. A Client contains<br></span></td></tr><tr id="sl_svn154_10"><td class="source"><span class="str">&nbsp; &nbsp;various streams from the client, represented using the Stream class.<br></span></td></tr><tr id="sl_svn154_11"><td class="source"><span class="str">3. The Message, Header and Command represent RTMP message, header and command respectively. The FLV class implements functions to perform read<br></span></td></tr><tr id="sl_svn154_12"><td class="source"><span class="str">&nbsp; &nbsp;and write of FLV file format.<br></span></td></tr><tr id="sl_svn154_13"><td class="source"><span class="str"><br></span></td></tr><tr id="sl_svn154_14"><td class="source"><span class="str"><br></span></td></tr><tr id="sl_svn154_15"><td class="source"><span class="str">Typically an application can launch this server as follows:<br></span></td></tr><tr id="sl_svn154_16"><td class="source"><span class="str">$ python rtmp.py<br></span></td></tr><tr id="sl_svn154_17"><td class="source"><span class="str"><br></span></td></tr><tr id="sl_svn154_18"><td class="source"><span class="str">To know the command line options use the -h option:<br></span></td></tr><tr id="sl_svn154_19"><td class="source"><span class="str">$ python rtmp.py -h<br></span></td></tr><tr id="sl_svn154_20"><td class="source"><span class="str"><br></span></td></tr><tr id="sl_svn154_21"><td class="source"><span class="str">To start the server with a different directory for recording and playing FLV files from, use the following command.<br></span></td></tr><tr id="sl_svn154_22"><td class="source"><span class="str">$ python rtmp.py -r some-other-directory/<br></span></td></tr><tr id="sl_svn154_23"><td class="source"><span class="str">Note the terminal '/' in the directory name. Without this, it is just used as a prefix in FLV file names.<br></span></td></tr><tr id="sl_svn154_24"><td class="source"><span class="str"><br></span></td></tr><tr id="sl_svn154_25"><td class="source"><span class="str">A test client is available in testClient directory, and can be compiled using Flex Builder. Alternatively, you can use the SWF file to launch<br></span></td></tr><tr id="sl_svn154_26"><td class="source"><span class="str">from testClient/bin-debug after starting the server. Once you have launched the client in the browser, you can connect to<br></span></td></tr><tr id="sl_svn154_27"><td class="source"><span class="str">local host by clicking on 'connect' button. Then click on publish button to publish a stream. Open another browser with<br></span></td></tr><tr id="sl_sv
<pre><table width="100%"><tbody><tr class="cursor_stop cursor_hidden"><td></td></tr></tbody></table></pre>
</td>
</tr></tbody></table>
<script type="text/javascript">
var lineNumUnderMouse = -1;
function gutterOver(num) {
gutterOut();
var newTR = document.getElementById('gr_svn154_' + num);
if (newTR) {
newTR.className = 'undermouse';
}
lineNumUnderMouse = num;
}
function gutterOut() {
if (lineNumUnderMouse != -1) {
var oldTR = document.getElementById(
'gr_svn154_' + lineNumUnderMouse);
if (oldTR) {
oldTR.className = '';
}
lineNumUnderMouse = -1;
}
}
var numsGenState = {table_base_id: 'nums_table_'};
var srcGenState = {table_base_id: 'src_table_'};
var alignerRunning = false;
var startOver = false;
function setLineNumberHeights() {
if (alignerRunning) {
startOver = true;
return;
}
numsGenState.chunk_id = 0;
numsGenState.table = document.getElementById('nums_table_0');
numsGenState.row_num = 0;
if (!numsGenState.table) {
return; // Silently exit if no file is present.
}
srcGenState.chunk_id = 0;
srcGenState.table = document.getElementById('src_table_0');
srcGenState.row_num = 0;
alignerRunning = true;
continueToSetLineNumberHeights();
}
function rowGenerator(genState) {
if (genState.row_num < genState.table.rows.length) {
var currentRow = genState.table.rows[genState.row_num];
genState.row_num++;
return currentRow;
}
var newTable = document.getElementById(
genState.table_base_id + (genState.chunk_id + 1));
if (newTable) {
genState.chunk_id++;
genState.row_num = 0;
genState.table = newTable;
return genState.table.rows[0];
}
return null;
}
var MAX_ROWS_PER_PASS = 1000;
function continueToSetLineNumberHeights() {
var rowsInThisPass = 0;
var numRow = 1;
var srcRow = 1;
while (numRow && srcRow && rowsInThisPass < MAX_ROWS_PER_PASS) {
numRow = rowGenerator(numsGenState);
srcRow = rowGenerator(srcGenState);
rowsInThisPass++;
if (numRow && srcRow) {
if (numRow.offsetHeight != srcRow.offsetHeight) {
numRow.firstChild.style.height = srcRow.offsetHeight + 'px';
}
}
}
if (rowsInThisPass >= MAX_ROWS_PER_PASS) {
setTimeout(continueToSetLineNumberHeights, 10);
} else {
alignerRunning = false;
if (startOver) {
startOver = false;
setTimeout(setLineNumberHeights, 500);
}
}
}
function initLineNumberHeights() {
// Do 2 complete passes, because there can be races
// between this code and prettify.
startOver = true;
setTimeout(setLineNumberHeights, 250);
window.onresize = setLineNumberHeights;
}
initLineNumberHeights();
</script>
<div id="log">
<div style="text-align:right">
<a class="ifCollapse" href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#" onclick="_toggleMeta(this); return false">Show details</a>
<a class="ifExpand" href="http://code.google.com/p/rtmplite/source/browse/trunk/rtmp.py#" onclick="_toggleMeta(this); return false">Hide details</a>
</div>
<div class="ifExpand">
<div class="pmeta_bubble_bg" style="border:1px solid white">
<div class="round4"></div>
<div class="round2"></div>
<div class="round1"></div>
<div class="box-inner">
<div id="changelog">
<p>Change log</p>
<div>
<a href="http://code.google.com/p/rtmplite/source/detail?spec=svn154&r=145">r145</a>
by kundan10
on Feb 6, 2012
&nbsp; <a href="http://code.google.com/p/rtmplite/source/diff?spec=svn154&r=145&format=side&path=/trunk/rtmp.py&old_path=/trunk/rtmp.py&old=142">Diff</a>
</div>
<pre>patch submitted by Teeed teeed@na1noc.pl
on Jan 16 to fix the result fron onCommand</pre>
</div>
<script type="text/javascript">
var detail_url = '/p/rtmplite/source/detail?r=145&spec=svn154';
var publish_url = '/p/rtmplite/source/detail?r=145&spec=svn154#publish';
// describe the paths of this revision in javascript.
var changed_paths = [];
var changed_urls = [];
changed_paths.push('/trunk/rtmp.py');
changed_urls.push('/p/rtmplite/source/browse/trunk/rtmp.py?r\x3d145\x26spec\x3dsvn154');
var selected_path = '/trunk/rtmp.py';
changed_paths.push('/trunk/siprtmp_gevent.py');
changed_urls.push('/p/rtmplite/source/browse/trunk/siprtmp_gevent.py?r\x3d145\x26spec\x3dsvn154');
function getCurrentPageIndex() {
for (var i = 0; i < changed_paths.length; i++) {
if (selected_path == changed_paths[i]) {
return i;
}
}
}
function getNextPage() {
var i = getCurrentPageIndex();
if (i < changed_paths.length - 1) {
return changed_urls[i + 1];
}
return null;
}
function getPreviousPage() {
var i = getCurrentPageIndex();
if (i > 0) {
return changed_urls[i - 1];
}
return null;
}
function gotoNextPage() {
var page = getNextPage();
if (!page) {
page = detail_url;
}
window.location = page;
}
function gotoPreviousPage() {
var page = getPreviousPage();
if (!page) {
page = detail_url;
}
window.location = page;
}
function gotoDetailPage() {
window.location = detail_url;
}
function gotoPublishPage() {
window.location = publish_url;
}
</script>
<style type="text/css">
#review_nav {
border-top: 3px solid white;
padding-top: 6px;
margin-top: 1em;
}
#review_nav td {
vertical-align: middle;
}
#review_nav select {
margin: .5em 0;
}
</style>
<div id="review_nav">
<table><tbody><tr><td>Go to:&nbsp;</td><td>
<select name="files_in_rev" onchange="window.location=this.value">
<option value="/p/rtmplite/source/browse/trunk/rtmp.py?r=145&amp;spec=svn154" selected="selected">/trunk/rtmp.py</option>
<option value="/p/rtmplite/source/browse/trunk/siprtmp_gevent.py?r=145&amp;spec=svn154">/trunk/siprtmp_gevent.py</option>
</select>
</td></tr></tbody></table>
</div>
</div>
<div class="round1"></div>
<div class="round2"></div>
<div class="round4"></div>
</div>
<div class="pmeta_bubble_bg" style="border:1px solid white">
<div class="round4"></div>
<div class="round2"></div>
<div class="round1"></div>
<div class="box-inner">
<div id="older_bubble">
<p>Older revisions</p>
<div class="closed" style="margin-bottom:3px;">
<img class="ifClosed" onclick="_toggleHidden(this)" src="./rtmp_files/plus.gif">
<img class="ifOpened" onclick="_toggleHidden(this)" src="./rtmp_files/minus.gif">
<a href="http://code.google.com/p/rtmplite/source/detail?spec=svn154&r=142">r142</a>
by kundan10
on Feb 5, 2012
&nbsp; <a href="http://code.google.com/p/rtmplite/source/diff?spec=svn154&r=142&format=side&path=/trunk/rtmp.py&old_path=/trunk/rtmp.py&old=141">Diff</a>
<br>
<pre class="ifOpened">reverting <a href="http://code.google.com/p/rtmplite/source/detail?r=141">r141</a> since it causes
exception in setting self.rpc because
rpc exists as a function</pre>
</div>
<div class="closed" style="margin-bottom:3px;">
<img class="ifClosed" onclick="_toggleHidden(this)" src="./rtmp_files/plus.gif">
<img class="ifOpened" onclick="_toggleHidden(this)" src="./rtmp_files/minus.gif">
<a href="http://code.google.com/p/rtmplite/source/detail?spec=svn154&r=141">r141</a>
by pratnama
on Jan 28, 2012
&nbsp; <a href="http://code.google.com/p/rtmplite/source/diff?spec=svn154&r=141&format=side&path=/trunk/rtmp.py&old_path=/trunk/rtmp.py&old=137">Diff</a>
<br>
<pre class="ifOpened">force self.rpc to be Message.RPC on
NetConnection.connect() even in AMF3.
AMF3 is fully working now</pre>
</div>
<div class="closed" style="margin-bottom:3px;">
<img class="ifClosed" onclick="_toggleHidden(this)" src="./rtmp_files/plus.gif">
<img class="ifOpened" onclick="_toggleHidden(this)" src="./rtmp_files/minus.gif">
<a href="http://code.google.com/p/rtmplite/source/detail?spec=svn154&r=137">r137</a>
by kundan10
on Jan 20, 2012
&nbsp; <a href="http://code.google.com/p/rtmplite/source/diff?spec=svn154&r=137&format=side&path=/trunk/rtmp.py&old_path=/trunk/rtmp.py&old=121">Diff</a>
<br>
<pre class="ifOpened">show media flow trace only for -D.
support streambegin and define FLV in
gevent version. ignore stream name
after ?. don't include objectEncoding
in connect success if connect did not
...</pre>
</div>
<a href="http://code.google.com/p/rtmplite/source/list?path=/trunk/rtmp.py&start=145">All revisions of this file</a>
</div>
</div>
<div class="round1"></div>
<div class="round2"></div>
<div class="round4"></div>
</div>
<div class="pmeta_bubble_bg" style="border:1px solid white">
<div class="round4"></div>
<div class="round2"></div>
<div class="round1"></div>
<div class="box-inner">
<div id="fileinfo_bubble">
<p>File info</p>
<div>Size: 65812 bytes,
1214 lines</div>
<div><a href="http://rtmplite.googlecode.com/svn/trunk/rtmp.py">View raw file</a></div>
</div>
<div id="props">
<p>File properties</p>
<dl>
<dt>svn:executable</dt>
<dd>*</dd>
<dt>svn:keywords</dt>
<dd>Author Id Revision Date</dd>
</dl>
</div>
</div>
<div class="round1"></div>
<div class="round2"></div>
<div class="round4"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="./rtmp_files/prettify.js"></script>
<script type="text/javascript">prettyPrint();</script>
<script src="./rtmp_files/source_file_scripts.js"></script>
<script type="text/javascript" src="./rtmp_files/kibbles-1.3.3.comp.js"></script>
<script type="text/javascript">
var lastStop = null;
var initialized = false;
function updateCursor(next, prev) {
if (prev && prev.element) {
prev.element.className = 'cursor_stop cursor_hidden';
}
if (next && next.element) {
next.element.className = 'cursor_stop cursor';
lastStop = next.index;
}
}
function pubRevealed(data) {
updateCursorForCell(data.cellId, 'cursor_stop cursor_hidden');
if (initialized) {
reloadCursors();
}
}
function draftRevealed(data) {
updateCursorForCell(data.cellId, 'cursor_stop cursor_hidden');
if (initialized) {
reloadCursors();
}
}
function draftDestroyed(data) {
updateCursorForCell(data.cellId, 'nocursor');
if (initialized) {
reloadCursors();
}
}
function reloadCursors() {
kibbles.skipper.reset();
loadCursors();
if (lastStop != null) {
kibbles.skipper.setCurrentStop(lastStop);
}
}
// possibly the simplest way to insert any newly added comments
// is to update the class of the corresponding cursor row,
// then refresh the entire list of rows.
function updateCursorForCell(cellId, className) {
var cell = document.getElementById(cellId);
// we have to go two rows back to find the cursor location
var row = getPreviousElement(cell.parentNode);
row.className = className;
}
// returns the previous element, ignores text nodes.
function getPreviousElement(e) {
var element = e.previousSibling;
if (element.nodeType == 3) {
element = element.previousSibling;
}
if (element && element.tagName) {
return element;
}
}
function loadCursors() {
// register our elements with skipper
var elements = CR_getElements('*', 'cursor_stop');
var len = elements.length;
for (var i = 0; i < len; i++) {
var element = elements[i];
element.className = 'cursor_stop cursor_hidden';
kibbles.skipper.append(element);
}
}
function toggleComments() {
CR_toggleCommentDisplay();
reloadCursors();
}
function keysOnLoadHandler() {
// setup skipper
kibbles.skipper.addStopListener(
kibbles.skipper.LISTENER_TYPE.PRE, updateCursor);
// Set the 'offset' option to return the middle of the client area
// an option can be a static value, or a callback
kibbles.skipper.setOption('padding_top', 50);
// Set the 'offset' option to return the middle of the client area
// an option can be a static value, or a callback
kibbles.skipper.setOption('padding_bottom', 100);
// Register our keys
kibbles.skipper.addFwdKey("n");
kibbles.skipper.addRevKey("p");
kibbles.keys.addKeyPressListener(
'u', function() { window.location = detail_url; });
kibbles.keys.addKeyPressListener(
'r', function() { window.location = detail_url + '#publish'; });
kibbles.keys.addKeyPressListener('j', gotoNextPage);
kibbles.keys.addKeyPressListener('k', gotoPreviousPage);
}
</script>
<script src="./rtmp_files/code_review_scripts.js"></script>
<script type="text/javascript">
function showPublishInstructions() {
var element = document.getElementById('review_instr');
if (element) {
element.className = 'opened';
}
}
var codereviews;
function revsOnLoadHandler() {
// register our source container with the commenting code
var paths = {'svn154': '/trunk/rtmp.py'}
codereviews = CR_controller.setup(
{"profileUrl":["/u/102069584091941751068/"],"token":"vVg-YEkpsP38PydkCFlVS-ioMOA:1335711600965","assetHostPath":"http://www.gstatic.com/codesite/ph","domainName":null,"assetVersionPath":"http://www.gstatic.com/codesite/ph/12151595242108277468","projectHomeUrl":"/p/rtmplite","relativeBaseUrl":"","projectName":"rtmplite","loggedInUserEmail":"arutyunyan.roman@gmail.com"}, '', 'svn154', paths,
CR_BrowseIntegrationFactory);
codereviews.registerActivityListener(CR_ActivityType.REVEAL_DRAFT_PLATE, showPublishInstructions);
codereviews.registerActivityListener(CR_ActivityType.REVEAL_PUB_PLATE, pubRevealed);
codereviews.registerActivityListener(CR_ActivityType.REVEAL_DRAFT_PLATE, draftRevealed);
codereviews.registerActivityListener(CR_ActivityType.DISCARD_DRAFT_COMMENT, draftDestroyed);
var initialized = true;
reloadCursors();
}
window.onload = function() {keysOnLoadHandler(); revsOnLoadHandler();};
</script>
<script type="text/javascript" src="./rtmp_files/dit_scripts.js"></script>
<script type="text/javascript" src="./rtmp_files/ph_core.js"></script>
<script type="text/javascript" src="./rtmp_files/codesite_product_dictionary_ph.pack.04102009.js"></script>
</div>
<div id="footer" dir="ltr">
<div class="text">
<a href="http://code.google.com/projecthosting/terms.html">Terms</a> -
<a href="http://www.google.com/privacy.html">Privacy</a> -
<a href="http://code.google.com/p/support/">Project Hosting Help</a>
</div>
</div>
<div class="hostedBy" style="margin-top: -20px;">
<span style="vertical-align: top;">Powered by <a href="http://code.google.com/projecthosting/">Google Project Hosting</a></span>
</div>
<div class="menuDiv instance0" id="menuDiv-projects-dropdown" style="position: absolute; display: none; top: 18px; left: 1144px; "><div class="menuCategory controls first"><hr class="menuSeparator"><a class="menuItem" style="display: block; " href="http://code.google.com/more/">Find developer products...</a><a class="menuItem" style="display: block; " href="http://code.google.com/hosting/">Find open source projects...</a></div></div></body></html>