protected void HandleLoginAttemptComplete(ErrorCode result) { if (Twitch.Error.Failed(result)) { MessageBox.Show("Login failed, please request another auth token"); } mChannelNameText.Text = mBroadcastController.UserName; mChatChannelText.Text = mBroadcastController.UserName; }
void IChatCallbacks.ChatChannelMessageCallback(ChatMessageList messageList) { for (int i = 0; i < messageList.Messages.Length; ++i) { m_Messages.AddLast(messageList.Messages[i]); } try { if (m_UseEmoticons) { if (TokenizedMessagesReceived != null) { List <ChatTokenizedMessage> list = new List <ChatTokenizedMessage>(); for (int i = 0; i < messageList.Messages.Length; ++i) { ChatTokenizedMessage tokenized = null; ErrorCode ret = m_Chat.TokenizeMessage(messageList.Messages[i], out tokenized); if (Error.Failed(ret) || tokenized == null) { string err = Error.GetString(ret); ReportError(string.Format("Error disconnecting: {0}", err)); } else { list.Add(tokenized); } } ChatTokenizedMessage[] arr = list.ToArray(); this.TokenizedMessagesReceived(arr); } } else { if (RawMessagesReceived != null) { this.RawMessagesReceived(messageList.Messages); } } } catch { } // cap the number of messages cached while (m_Messages.Count > m_MessageHistorySize) { m_Messages.RemoveFirst(); } }
/// <summary> /// Runs a commercial on the channel. Must be broadcasting. /// </summary> /// <returns>Whether or not successful</returns> public virtual bool RunCommercial() { if (!this.IsBroadcasting) { return(false); } ErrorCode err = m_Stream.RunCommercial(m_AuthToken); CheckError(err); return(Error.Succeeded(err)); }
protected void FireFrameSubmissionIssue(ErrorCode ret) { try { if (this.FrameSubmissionIssue != null) { this.FrameSubmissionIssue(ret); } } catch (Exception x) { ReportError(x.ToString()); } }
protected virtual void DownloadEmoticonData() { if (m_UseEmoticons && !m_EmoticonDataDownloaded && m_ChatInitialized) { ErrorCode ret = m_Chat.DownloadEmoticonData(); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error trying to download emoticon data: {0}", err)); } } }
/// <summary> /// Send a singular action metadata point to Twitch's metadata service. /// </summary> /// <param name="name">A specific name for an event meant to be queryable</param> /// <param name="streamTime">Number of milliseconds into the broadcast for when event occurs</param> /// <param name="humanDescription">Long form string to describe the meaning of an event. Maximum length is 1000 characters</param> /// <param name="data">A valid JSON object that is the payload of an event. Values in this JSON object have to be strings. Maximum of 50 keys are allowed. Maximum length for values are 255 characters.</param> /// <returns>True if submitted and no error, false otherwise.</returns> public virtual bool SendActionMetaData(string name, UInt64 streamTime, string humanDescription, string data) { ErrorCode ret = m_Stream.SendActionMetaData(m_AuthToken, name, streamTime, humanDescription, data); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error while sending meta data: {0}\n", err)); return(false); } return(true); }
protected void HandleGameNameListReceived(ErrorCode result, Twitch.Broadcast.GameInfo[] list) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < list.Length; ++i) { if (i > 0) { sb.Append(", "); } sb.Append(list[i].Name); } MessageBox.Show(sb.ToString()); }
/// <summary> /// Send the beginning datapoint of an event that has a beginning and end. /// </summary> /// <param name="name">A specific name for an event meant to be queryable</param> /// <param name="streamTime">Number of milliseconds into the broadcast for when event occurs</param> /// <param name="sequenceId">A unique sequenceId returned that associates a start and end event together</param> /// <param name="humanDescription">Long form string to describe the meaning of an event. Maximum length is 1000 characters</param> /// <param name="data">A valid JSON object that is the payload of an event. Values in this JSON object have to be strings. Maximum of 50 keys are allowed. Maximum length for values are 255 characters.</param> /// <returns>True if submitted and no error, false otherwise.</returns> public virtual bool StartSpanMetaData(string name, UInt64 streamTime, out ulong sequenceId, string humanDescription, string data) { sequenceId = 0xFFFFFFFFFFFFFFFF; ErrorCode ret = m_Stream.SendStartSpanMetaData(m_AuthToken, name, streamTime, out sequenceId, humanDescription, data); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error in SendStartSpanMetaData: {0}\n", err)); return(false); } return(true); }
protected void HandleAuthTokenRequestComplete(ErrorCode result, AuthToken authToken) { if (Twitch.Error.Failed(result)) { MessageBox.Show("Auth token request failed, please check your username and password and try again"); } else { // cache the auth token for reuse on consecutive runs try { System.IO.File.WriteAllText(kAuthTokenFile, authToken.Data); } catch (Exception x) { MessageBox.Show(x.ToString()); } } }
/// <summary> /// Sends a chat message to the channel. /// </summary> /// <param name="message">The message to send.</param> /// <returns>Whether or not the attempt was valid.</returns> public virtual bool SendChatMessage(string message) { if (m_ChatState != ChatState.Connected) { return(false); } ErrorCode ret = m_Chat.SendMessage(message); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error sending chat message: {0}", err)); return(false); } return(true); }
void IStreamCallbacks.GetGameNameListCallback(ErrorCode result, GameInfoList list) { if (Error.Failed(result)) { string err = Error.GetString(result); ReportError(string.Format("GameNameListCallback got failure: {0}", err)); } try { if (GameNameListReceived != null) { this.GameNameListReceived(result, list == null ? new GameInfo[0] : list.List); } } catch (Exception x) { ReportError(x.ToString()); } }
/// <summary> /// Send the ending datapoint of an event that has a beginning and end. /// </summary> /// <param name="name">A specific name for an event meant to be queryable</param> /// <param name="streamTime">Number of milliseconds into the broadcast for when event occurs</param> /// <param name="sequenceId">Associates a start and end event together. Use the corresponding sequenceId returned in TTV_SendStartSpanMetaData</param> /// <param name="humanDescription">Long form string to describe the meaning of an event. Maximum length is 1000 characters</param> /// <param name="data">A valid JSON object that is the payload of an event. Values in this JSON object have to be strings. Maximum of 50 keys are allowed. Maximum length for values are 255 characters.</param> /// <returns>True if submitted and no error, false otherwise.</returns> public virtual bool EndSpanMetaData(string name, UInt64 streamTime, ulong sequenceId, string humanDescription, string data) { if (sequenceId == 0xFFFFFFFFFFFFFFFF) { ReportError(string.Format("Invalid sequenceId: {0}\n", sequenceId)); return(false); } ErrorCode ret = m_Stream.SendEndSpanMetaData(m_AuthToken, name, streamTime, sequenceId, humanDescription, data); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error in SendStopSpanMetaData: {0}\n", err)); return(false); } return(true); }
/// <summary> /// Terminates the broadcast. /// </summary> /// <returns>Whether or not successfully stopped</returns> public virtual bool StopBroadcasting() { if (!this.IsBroadcasting) { return(false); } ErrorCode ret = m_Stream.Stop(true); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error while stopping the broadcast: {0}", err)); return(false); } SetBroadcastState(BroadcastState.Stopping); return(true); }
protected virtual void UpdateStreamInfo() { System.DateTime now = System.DateTime.Now; System.TimeSpan delta = now - m_LastStreamInfoUpdateTime; // only check every so often if (delta.TotalSeconds < s_StreamInfoUpdateInterval) { return; } m_LastStreamInfoUpdateTime = now; ErrorCode ret = m_Stream.GetStreamInfo(m_AuthToken, m_UserName); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error in TTV_GetStreamInfo: {0}\n", err)); } }
void IStreamCallbacks.StopCallback(ErrorCode ret) { if (Error.Succeeded(ret)) { m_VideoParams = null; m_AudioParams = null; CleanupBuffers(); try { if (BroadcastStopped != null) { this.BroadcastStopped(); } } catch (Exception x) { ReportError(x.ToString()); } if (m_LoggedIn) { SetBroadcastState(BroadcastState.ReadyToBroadcast); } else { SetBroadcastState(BroadcastState.Initialized); } } else { // there's not really a good state to go into here SetBroadcastState(BroadcastState.ReadyToBroadcast); string err = Error.GetString(ret); ReportError(string.Format("StopCallback got failure: {0}", err)); } }
/// <summary> /// Begins broadcast using the given VideoParams. /// </summary> /// <param name="videoParams">The video params</param> /// <returns>Whether or not successfully broadcasting</returns> public virtual bool StartBroadcasting(VideoParams videoParams) { if (videoParams == null || !this.IsReadyToBroadcast) { return(false); } m_VideoParams = videoParams.Clone() as VideoParams; // Setup the audio parameters m_AudioParams = new AudioParams(); m_AudioParams.AudioEnabled = this.EnableAudio && this.IsAudioSupported; // only enable audio if possible if (!AllocateBuffers()) { m_VideoParams = null; m_AudioParams = null; return(false); } ErrorCode ret = m_Stream.Start(videoParams, m_AudioParams, m_IngestServer, StartFlags.None, true); if (Error.Failed(ret)) { CleanupBuffers(); string err = Error.GetString(ret); ReportError(string.Format("Error while starting to broadcast: {0}", err)); m_VideoParams = null; m_AudioParams = null; return(false); } SetBroadcastState(BroadcastState.Starting); return(true); }
protected virtual bool Shutdown() { if (m_ChatInitialized) { ErrorCode ret = m_Chat.Shutdown(); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error shutting down chat: {0}", err)); return(false); } } m_ChatState = ChatState.Uninitialized; m_ChatInitialized = false; CleanupEmoticonData(); m_Chat.ChatCallbacks = null; return(true); }
/// <summary> /// Pauses the current broadcast and displays the default pause screen. /// </summary> /// <returns>Whether or not successfully paused</returns> public virtual bool PauseBroadcasting() { if (!this.IsBroadcasting) { return(false); } ErrorCode ret = m_Stream.PauseVideo(); if (Error.Failed(ret)) { // not streaming anymore StopBroadcasting(); string err = Error.GetString(ret); ReportError(string.Format("Error pausing broadcast: {0}\n", err)); } else { SetBroadcastState(BroadcastState.Paused); } return(Error.Succeeded(ret)); }
void IStreamCallbacks.GetStreamInfoCallback(ErrorCode result, StreamInfo streamInfo) { if (Error.Succeeded(result)) { m_StreamInfo = streamInfo; try { if (StreamInfoUpdated != null) { StreamInfoUpdated(streamInfo); } } catch (Exception x) { ReportError(x.ToString()); } } else { //string err = Error.GetString(result); //ReportWarning(string.Format("StreamInfoDoneCallback got failure: {0}", err)); } }
/// <summary> /// Returns a fully populated VideoParams struct based on the given width, height and frame rate. /// /// This function is not the advised way to setup VideoParams because it has no information about the user's maximum bitrate. /// Use the other version of GetRecommendedVideoParams instead if possible. /// </summary> /// <param name="width">The broadcast width</param> /// <param name="height">The broadcast height</param> /// <param name="frameRate">The broadcast frames per second</param> /// <returns>The VideoParams</returns> public virtual VideoParams GetRecommendedVideoParams(uint width, uint height, uint frameRate) { VideoParams videoParams = new VideoParams(); videoParams.OutputWidth = width; videoParams.OutputHeight = height; videoParams.TargetFps = frameRate; videoParams.PixelFormat = DeterminePixelFormat(); videoParams.EncodingCpuUsage = EncodingCpuUsage.TTV_ECU_HIGH; videoParams.DisableAdaptiveBitrate = false; videoParams.VerticalFlip = false; // Compute the rest of the fields based on the given parameters ErrorCode ret = m_Stream.GetDefaultParams(videoParams); if (Error.Failed(ret)) { String err = Error.GetString(ret); ReportError(String.Format("Error in GetDefaultParams: {0}", err)); return(null); } return(videoParams); }
protected virtual void CheckError(ErrorCode err) { }
/// <summary> /// Updates the internals of the controller. This should be called at least as frequently as the desired broadcast framerate. /// Asynchronous results will be fired from inside this function. /// </summary> public virtual void Update() { // for stress testing to make sure memory is being passed around properly //GC.Collect(); if (m_Stream == null || !m_SdkInitialized) { return; } ErrorCode ret = m_Stream.PollTasks(); CheckError(ret); // update the ingest tester if (this.IsIngestTesting) { m_IngestTester.Update(); // all done testing if (m_IngestTester.IsDone) { m_IngestTester = null; SetBroadcastState(BroadcastState.ReadyToBroadcast); } } switch (m_BroadcastState) { // Kick off an authentication request case BroadcastState.Authenticated: { SetBroadcastState(BroadcastState.LoggingIn); ret = m_Stream.Login(m_AuthToken); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error in TTV_Login: {0}\n", err)); } break; } // Login case BroadcastState.LoggedIn: { SetBroadcastState(BroadcastState.FindingIngestServer); ret = m_Stream.GetIngestServers(m_AuthToken); if (Error.Failed(ret)) { SetBroadcastState(BroadcastState.LoggedIn); string err = Error.GetString(ret); ReportError(string.Format("Error in TTV_GetIngestServers: {0}\n", err)); } break; } // Ready to stream case BroadcastState.ReceivedIngestServers: { SetBroadcastState(BroadcastState.ReadyToBroadcast); // Kick off requests for the user and stream information that aren't 100% essential to be ready before streaming starts ret = m_Stream.GetUserInfo(m_AuthToken); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error in TTV_GetUserInfo: {0}\n", err)); } UpdateStreamInfo(); ret = m_Stream.GetArchivingState(m_AuthToken); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error in TTV_GetArchivingState: {0}\n", err)); } break; } // Waiting for the start/stop callback case BroadcastState.Starting: case BroadcastState.Stopping: { break; } // No action required case BroadcastState.FindingIngestServer: case BroadcastState.Authenticating: case BroadcastState.Initialized: case BroadcastState.Uninitialized: case BroadcastState.IngestTesting: { break; } case BroadcastState.Broadcasting: case BroadcastState.Paused: { UpdateStreamInfo(); break; } default: { break; } } }
void IStreamCallbacks.LoginCallback(ErrorCode result, ChannelInfo channelInfo) { if (Error.Succeeded(result)) { m_ChannelInfo = channelInfo; SetBroadcastState(BroadcastState.LoggedIn); m_LoggedIn = true; } else { SetBroadcastState(BroadcastState.Initialized); m_LoggedIn = false; string err = Error.GetString(result); ReportError(string.Format("LoginCallback got failure: {0}", err)); } try { if (LoginAttemptComplete != null) { this.LoginAttemptComplete(result); } } catch (Exception x) { ReportError(x.ToString()); } }
/// <summary> /// Periodically updates the internal state of the controller. /// </summary> public virtual void Update() { // for stress testing to make sure memory is being passed around properly //GC.Collect(); if (!m_ChatInitialized) { return; } ErrorCode ret = m_Chat.FlushEvents(); if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error flushing chat events: {0}", err)); } switch (m_ChatState) { case ChatState.Uninitialized: { break; } case ChatState.Initialized: { // connect to the channel if (m_Anonymous) { ret = m_Chat.ConnectAnonymous(); } else { ret = m_Chat.Connect(m_ChannelName, m_AuthToken.Data); } if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("Error connecting: {0}", err)); Shutdown(); FireDisconnected(); } else { m_ChatState = ChatState.Connecting; DownloadEmoticonData(); } break; } case ChatState.Connecting: { break; } case ChatState.Connected: { break; } case ChatState.Disconnected: { Disconnect(); break; } } }
void IChatCallbacks.EmoticonDataDownloadCallback(ErrorCode error) { // grab the texture and badge data if (Error.Succeeded(error)) { SetupEmoticonData(); } }
protected void HandleFrameSubmissionIssue(ErrorCode result) { // if you are receiving TTV_WRN_QUEUELENGTH then it's possible the bitrate is too high for the user's internet connection DebugOverlay.Instance.AddViewportText("FrameSubmissionIssue: " + result.ToString(), 1); }
void IStreamCallbacks.StartCallback(ErrorCode ret) { if (Error.Succeeded(ret)) { try { if (BroadcastStarted != null) { this.BroadcastStarted(); } } catch (Exception x) { ReportError(x.ToString()); } SetBroadcastState(BroadcastState.Broadcasting); } else { m_VideoParams = null; m_AudioParams = null; SetBroadcastState(BroadcastState.ReadyToBroadcast); string err = Error.GetString(ret); ReportError(string.Format("StartCallback got failure: {0}", err)); } }
void IStreamCallbacks.SetStreamInfoCallback(ErrorCode result) { if (Error.Failed(result)) { string err = Error.GetString(result); ReportWarning(string.Format("SetStreamInfoCallback got failure: {0}", err)); } }
void IStreamCallbacks.GetArchivingStateCallback(ErrorCode result, ArchivingState state) { m_ArchivingState = state; if (Error.Failed(result)) { //string err = Error.GetString(result); //ReportWarning(string.Format("ArchivingStateDoneCallback got failure: {0}", err)); } }
void IStreamCallbacks.SendStartSpanMetaDataCallback(ErrorCode ret) { if (Error.Failed(ret)) { string err = Error.GetString(ret); ReportError(string.Format("SendStartSpanMetaDataCallback got failure: {0}", err)); } }
void IStreamCallbacks.GetIngestServersCallback(ErrorCode result, IngestList ingestList) { if (Error.Succeeded(result)) { m_IngestList = ingestList; // assume we're going to use the default ingest server unless overidden by the client m_IngestServer = m_IngestList.DefaultServer; SetBroadcastState(BroadcastState.ReceivedIngestServers); try { if (IngestListReceived != null) { IngestListReceived(ingestList); } } catch (Exception x) { ReportError(x.ToString()); } } else { string err = Error.GetString(result); ReportError(string.Format("IngestListCallback got failure: {0}", err)); // try again SetBroadcastState(BroadcastState.LoggedIn); } }
void IStreamCallbacks.GetUserInfoCallback(ErrorCode result, UserInfo userInfo) { m_UserInfo = userInfo; if (Error.Failed(result)) { string err = Error.GetString(result); ReportError(string.Format("UserInfoDoneCallback got failure: {0}", err)); } }
void IStreamCallbacks.RequestAuthTokenCallback(ErrorCode result, AuthToken authToken) { if (Error.Succeeded(result)) { // Now that the user is authorized the information can be requested about which server to stream to m_AuthToken = authToken; SetBroadcastState(BroadcastState.Authenticated); } else { m_AuthToken.Data = ""; SetBroadcastState(BroadcastState.Initialized); string err = Error.GetString(result); ReportError(string.Format("RequestAuthTokenDoneCallback got failure: {0}", err)); } try { if (AuthTokenRequestComplete != null) { this.AuthTokenRequestComplete(result, authToken); } } catch (Exception x) { ReportError(x.ToString()); } }
void IChatCallbacks.ChatStatusCallback(ErrorCode result) { if (Error.Succeeded(result)) { return; } m_ChatState = ChatState.Disconnected; }