// Called periodically on every UI update
JNIEXPORT void Java_com_superpowered_hlsexample_MainActivity_UpdateStatus(JNIEnv *javaEnvironment, jobject self) {
    jclass thisClass = javaEnvironment->GetObjectClass(self);
    //setFloatField(javaEnvironment, self, thisClass, "bufferStartPercent", player->bufferStartPercent);
    setFloatField(javaEnvironment, self, thisClass, "bufferEndPercent", player->bufferEndPercent);
    setLongField(javaEnvironment, self, thisClass, "durationSeconds", player->durationSeconds);
    setLongField(javaEnvironment, self, thisClass, "positionSeconds", player->positionSeconds);
    setFloatField(javaEnvironment, self, thisClass, "positionPercent", player->positionPercent);
    setBoolField(javaEnvironment, self, thisClass, "playing", player->playing);
}
Exemple #2
0
void MyFmsAuthorizeEvent::authorize()
{
	bool bAuthorized = true;  // default authorization state
	
	switch(m_pAev->getType())
	{
		case IFmsAuthEvent::E_APPSTART:
		{
			// only E_APPSTART allows changes to the following fields: 
			// F_APP_PRTMP
			// F_APP_PRTMP_COMMON_KEY_FILE
			// F_APP_PRTMP_VIDEO_ENC_LEVEL
			// F_APP_PRTMP_UPDATE_INTERVAL
			// F_APP_PRTMP_SWF_VERIFICATION
			// F_APP_PRTMP_SWF_WHITELIST_FOLDER
			bool bSet;
			I8 sValue;
			if (getI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP, sValue))
			{
				bSet = setI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP, sValue);
			}

			char* pCommonKeyPath = getStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_COMMON_KEY_FILE); 
			if (pCommonKeyPath)
			{				
				bSet = setStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_COMMON_KEY_FILE, 
					pCommonKeyPath);					
			}
			
			U32 uValue;
			if (getU32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_VIDEO_ENC_LEVEL, uValue))
			{
				bSet = setU32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_VIDEO_ENC_LEVEL, uValue);
			}

			I32 iValue;
			if (getI32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_UPDATE_INTERVAL, iValue))
			{
				bSet = setI32Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_UPDATE_INTERVAL, iValue);
			}

			if (getI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_VERIFICATION, sValue))
			{
				bSet = setI8Field(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_VERIFICATION, sValue);
			}

			char* pWhiteListPath = getStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_WHITELIST_FOLDER); 
			if (pWhiteListPath)
			{				
				bSet = setStringField(m_pAev, IFmsAuthEvent::F_APP_PRTMP_SWF_WHITELIST_FOLDER, 
					pWhiteListPath);					
			}

			bAuthorized = true;	
			
		}
		break;	
		case IFmsAuthEvent::E_CONNECT:
		{
			// only E_CONNECT allows changes to the following fields: 
			// F_CLIENT_AUDIO_SAMPLE_ACCESS
			// F_CLIENT_AUDIO_SAMPLE_ACCESS_LOCK
			// F_CLIENT_READ_ACCESS
			// F_CLIENT_READ_ACCESS_LOCK
			// F_CLIENT_VIDEO_SAMPLE_ACCESS
			// F_CLIENT_VIDEO_SAMPLE_ACCESS_LOCK
			// F_CLIENT_WRITE_ACCESS_LOCK
			// F_CLIENT_WRITE_ACCESS
			I8 iValue;
			if (getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS, iValue))
			{
				setI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_WRITE_ACCESS, iValue);
			}

			// redirect connection example
			char* pUri = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_URI); 
			if (pUri && !strcmp(pUri, "rtmp://localhost/streamtest"))
			{				
				setStringField(m_pAev, IFmsAuthEvent::F_CLIENT_REDIRECT_URI, 
					"rtmp://localhost:1935/streamtest");
				bAuthorized = false;	
			}

			// set DiffServ fields based on a client IP 
			// char* pIp = getStringField(m_pAev, IFmsAuthEvent::F_CLIENT_IP); 
			// if (pIp && !strcmp(pIp, "192.168.1.1"))
			{				
				// set the DSCP bits and mask
				U8 m_diffServBits = 170;
				U8 m_diffServMask = 252;
				setU8Field(m_pAev, IFmsAuthEvent::F_CLIENT_DIFFSERV_BITS, m_diffServBits);
				setU8Field(m_pAev, IFmsAuthEvent::F_CLIENT_DIFFSERV_MASK, m_diffServMask);

				bAuthorized = true;	
			}
		}
		break;	
		case IFmsAuthEvent::E_PLAY:
		{			
			char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); 
			if (pStreamName)
			{
				setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName);
			}			
			char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
			if (pStreamType)
			{
				setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType);
			}			
			char* pStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY);
			if (pStreamQuery)
			{
				setStringField(m_pAev, IFmsAuthEvent::F_STREAM_QUERY, pStreamQuery);
			}			
			m_pFmsAuthServerContext->log(pStreamName, IFmsServerContext::kInformation, false);
			m_pFmsAuthServerContext->log(pStreamType, IFmsServerContext::kInformation, false);
			m_pFmsAuthServerContext->log(pStreamQuery, IFmsServerContext::kInformation, false);

			I8 iValue;
			if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, iValue))
			{
				// If iValue is 1 (true) the playlist will be reset and the 
				// stream will be the only stream in the playlist; otherwise 
				// 0 (false) means the stream will be added to the existing
				// playlist.
				setI8Field(m_pAev, IFmsAuthEvent::F_STREAM_RESET, iValue);	
			}
			if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, iValue))
			{
				// If iValue is 1 (true) the stream timestamps will be ignored;
				// otherwise 0 (false) means the timestamps will be handled.
				setI8Field(m_pAev, IFmsAuthEvent::F_STREAM_IGNORE, iValue);	
			}
			
			char* pStreamTransition = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TRANSITION); 
			if (pStreamTransition && strlen(pStreamTransition))
			{				
				// MBR transition example
				if (!strcmp(pStreamTransition, "switch") ||
					!strcmp(pStreamTransition, "swap"))
				{					
					// get the old stream's properties 
					char* pOldStreamName = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_NAME);
					char* pOldStreamType = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_TYPE);
					char* pOldStreamQuery = getStringField(m_pAev, IFmsAuthEvent::F_OLD_STREAM_QUERY);

					// if pOldStream is empty (optional for switch) current stream is in play
					// do we really want stream transition? 	
					{
						// no we do not allow transition
						// bAuthorized = false;
						// now transition will be turned off and old stream continue playing
						// break;					
					}
					// doing nothing will execute transition mode as is
					// or you could modify transition by changing transition properties

					// set it to 1 to indicate they will be hooking up the stream, 
					// but that it does not currently exist
					setI32Field(m_pAev, IFmsAuthEvent::F_STREAM_LIVE_PUBLISH_PENDING, 1);	
				}	

				// get the offset value if transition is set to offset mode for reconnect
				if (!strcmp(pStreamTransition, "resume"))
				{
					float fValue;
					if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_OFFSET, fValue))
					{
						float offset = fValue; //offset value in seconds
					}			
				}
			}
			else
			{
				// This is a regular play waiting for approval, which may be converted
				// into a play2 command by changing transition properties
			}	
		}
		break;
		case IFmsAuthEvent::E_PUBLISH:
		{	
			char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); 
			if (pStreamName)
			{
				setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName);
			}	
			char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
			if (pStreamType)
			{
				setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType);
			}
			I32 iValue;
			if (getI32Field(m_pAev, IFmsAuthEvent::F_STREAM_PUBLISH_TYPE, iValue))
			{
				// publish types:
				// 0 : record
				// 1 : append
				// 2 : appendWithGap
				// -1 : live
				setI32Field(m_pAev, IFmsAuthEvent::F_STREAM_PUBLISH_TYPE, iValue);	
			}
		} 		
		break;
		case IFmsAuthEvent::E_FILENAME_TRANSFORM:
			{
				I64 iValue;
				if (getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, iValue))
				{
					// some fields are not eligible to be modified. The return
					// value will be false when trying to modify the F_CLIENT_ID.
					bool bSet = setI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_ID, iValue); 
				}
				char* pStreamName = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME); 
				if (pStreamName)
				{
					// some fields are not eligible to be modified. The return
					// value will be false when trying to modify the F_STREAM_NAME.
					bool bSet = setStringField(m_pAev, IFmsAuthEvent::F_STREAM_NAME, pStreamName); 
				}
				char* pStreamPath = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH); 
				if (pStreamPath)
				{
					setStringField(m_pAev, IFmsAuthEvent::F_STREAM_PATH, pStreamPath);
				}				
				char* pStreamType = getStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE);
				if (pStreamType)
				{
					setStringField(m_pAev, IFmsAuthEvent::F_STREAM_TYPE, pStreamType);		
				}						
			}
		break;
		case IFmsAuthEvent::E_PAUSE:
		{
			bAuthorized = false; // block all E_PAUSE events.
						
			float fValue;
			if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE_TIME, fValue))
			{
				float fPauseTime = fValue;	// in seconds
			}		
			
			I8 iValue;
			if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE, iValue))
			{
				// 1 (true) means PAUSE
				// 0 (false) means UNPAUSE
				bool boolPause = iValue != 0;	
			}			
			if (getI8Field(m_pAev, IFmsAuthEvent::F_STREAM_PAUSE_TOGGLE, iValue))
			{
				// 1 (true) means PAUSE_TOGGLE
				// 0 (false) means no PAUSE_TOGGLE was set
				bool boolPauseToggle = iValue != 0;	
			}	
		
			FmsVariant field;
			
			// Notify Action example: An IFmsNofifyAction is created to notify
			// server side action script (SSAS) of the E_PAUSE event by calling
			// the function name "method" in the script.  In this example two
			// variables will be passed to "method" by calling addParam(field)
			// on the action.
			if (m_pAev->getField(IFmsAuthEvent::F_CLIENT_ID, field) == IFmsAuthEvent::S_SUCCESS)
			{
				I64 clientId = field.i64;
				IFmsNotifyAction* pAction = m_pAev->addNotifyAction("Notified by adaptor");
				pAction->setClientId(field);
				const char mtd[] = "method";
				field.setString(reinterpret_cast<I8*>(const_cast<char*>(mtd)));
				pAction->setMethodName(field);

				// create and insert a U16 "12345" as the first parameter 
				field.setU16(12345);
				pAction->addParam(field);

				// create and insert clientId as a double as the second parameter 
				field.setDouble((double)clientId);
				pAction->addParam(field);
				
				// Note: SSAS does not work with I64 or Buffer variants
				// field.setI64(clientId); 
				// pAction->addParam(field); // incorrect
			}
		}
		break;
		case IFmsAuthEvent::E_SEEK:
		{
			bAuthorized = false; // block all E_SEEK events
			
			float fValue;
			if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fValue))
			{
				// Modification of the seek position example:
				// fValue + 3; will add 3 seconds to the initial seek posistion
				float fSeekTime = fValue; // value in seconds
				setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_SEEK_POSITION, fSeekTime);
			}			
		}
		break;
		case IFmsAuthEvent::E_LOADSEGMENT:
		{
			// bAuthorized = false;	// block all E_LOADSEGMENT events
			// E_LOADSEGMENT is a read only event that substitutes E_PLAY on 
			// FMS Origin servers for recorded streams.
			
			I64 iValue;	
			if (getI64Field(m_pAev, IFmsAuthEvent::F_SEGMENT_START, iValue))
			{
				I64 iStart = iValue; // in bytes
			}			
			if (getI64Field(m_pAev, IFmsAuthEvent::F_SEGMENT_END, iValue))
			{
				I64 iEnd = iValue;	// in bytes
			}			
		}
		break;
		case IFmsAuthEvent::E_RECORD:
		{
			// bAuthorized = false;	// block all E_RECORD events
			float fValue;	
			if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, fValue))
			{
				float recMaxSize = fValue; // in kilobytes
				setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXSIZE, recMaxSize);
			}			
			if (getFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, fValue))
			{
				float recMaxDuration = fValue;	// in seconds
				setFloatField(m_pAev, IFmsAuthEvent::F_STREAM_RECORD_MAXDURATION, recMaxDuration);
			}	
		}
		break;
		case IFmsAuthEvent::E_SWF_VERIFY:
		{
			// SWF Verification example:
			// kAuthorizeSwfVerification is assigned false by default.  The
			// target SWF file must be updated for this to work.
			if(kAuthorizeSwfVerification) 
			{
				I8 swfvVersion = 0;
				if(getI8Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_VERSION, swfvVersion))
				{
					std::stringstream stream;
					stream << "Swf verification version is " << static_cast<int>(swfvVersion);
					m_pFmsAuthServerContext->log(stream.str().c_str(), IFmsServerContext::kInformation, false);
				}
				I64 swfvDepth;
				if(getI64Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_DEPTH, swfvDepth))
				{				
					I32 swfvTTL;
					if(getI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, swfvTTL))
					{
						swfvTTL /= 2;
						setI32Field(m_pAev, IFmsAuthEvent::F_CLIENT_SWFV_TTL, swfvTTL);
					}

					U8 digest[kSHA256DigestLen];

					// Target a real SWF file instead of sample.swf 
					hashSwfFileAtDepth("C:\\sample.swf", swfvDepth, digest);

					FmsVariant field;
					field.setBuffer(digest, kSHA256DigestLen);	
					m_pAev->setField(IFmsAuthEvent::F_CLIENT_SWFV_DIGEST, field);
				}
			}			
		}
		break;
		
		case IFmsAuthEvent::E_APPSTOP:
		case IFmsAuthEvent::E_DISCONNECT:
		case IFmsAuthEvent::E_STOP:
		case IFmsAuthEvent::E_UNPUBLISH:
		case IFmsAuthEvent::E_ACTION:
		case IFmsAuthEvent::E_CODEC_CHANGE:
		case IFmsAuthEvent::E_RECORD_STOP:
		case IFmsAuthEvent::E_CLIENT_PAUSE:
		case IFmsAuthEvent::E_SWF_VERIFY_COMPLETE:
		case IFmsAuthEvent::E_CLIENT_SEEK:
		case IFmsAuthEvent::E_START_TRANSMIT:
		case IFmsAuthEvent::E_STOP_TRANSMIT:
		case IFmsAuthEvent::E_MAXEVENT:
		break;
	}
	
	IFmsAuthServerContext2::AuthFailureDesc* desc = NULL;
	
	if(!bAuthorized)
	{
		desc = new IFmsAuthServerContext2::AuthFailureDesc("Blocked by auth adaptor", 
			IFmsAuthServerContext2::kDefaultStatus, -1);
	}		
	char buf[1024];
	const char* const action = bAuthorized ? "approved" : "rejected";
	sprintf(buf, "Received dddd authorization type=%d id=%p %s\n", m_pAev->getType(), 
		m_pAev, action);

	char tlog[1024];
	sprintf(tlog,"bb\n");
	m_pFmsAuthServerContext->log(tlog, IFmsServerContext::kInformation, false) 
	
	// log to the configured FMS log directory. If the third parameter is true,
	// also send the log to the system event log.
	m_pFmsAuthServerContext->log(buf, IFmsServerContext::kInformation, false); 
	
	m_pFmsAuthServerContext->onAuthorize(m_pAev, bAuthorized, desc);
	delete desc;
}