Quantcast
Channel: Active questions tagged youtube-api - Stack Overflow
Viewing all articles
Browse latest Browse all 3831

Youtube Data API streaming issue

$
0
0

I'm a software developer and we are working on a new app (stream.attn.live). We have a strange problem, streaming from our platform (stream.attn.live), because sometimes we have only scheduled stream and not going live after that. The code we are using is the same and that happens with a specific Youtube account and very rarely with others. This is a link for one of my tests: https://www.youtube.com/watch?v=9oQW4JmY9YEIt always stays scheduled, but with other YT accounts it goes live. Sometimes that also happens with other accounts, but always with the mentioned one. I can't find any logic behind that, because I tried a lot of things, did a lot of researches and nothing changed at all. I added our main code for YT broadcasting below. Another problem is that if a user stops the stream without any silence at the end (1,2 seconds), it cuts the last 2,3 seconds from the end of the stream. If there is silence, it is the whole stream recorded. Please feel free to ask me some questions and I will try to provide you with some additional info. Thanks in advance!Best regards,Svetoslav Kazakov

using AttnLive.Data.Models;using AttnLive.Web.Services.Contracts;using Google.Apis.Auth.OAuth2;using Google.Apis.Auth.OAuth2.Flows;using Google.Apis.Auth.OAuth2.Responses;using Google.Apis.Services;using Google.Apis.Util.Store;using Google.Apis.YouTube.v3;using Google.Apis.YouTube.v3.Data;using System;using System.Diagnostics;using System.IO;using System.Threading;using System.Threading.Tasks;namespace AttnLive.Web.Services{    public class YouTubeLiveStreaming    {        private readonly IUsersService _usersService;        public StreamingYouTubeOptions Options { get; } //set only via Secret Manager        public YouTubeLiveStreaming(            IUsersService usersService,            StreamingYouTubeOptions optionsAccessor)        {            this._usersService = usersService;            this.Options = optionsAccessor;        }        public async Task<String> CreateLiveBroadcastEventAsync(            UserAccounts userAccount, String title,            String description,            DateTime eventStartDate,            bool? youtubeIsPublic)        {            string watchUrl = "-2";            try            {                //UserCredential credentials;                string[] scopes = new string[] { "https://www.googleapis.com/auth/youtube" }; // user basic profile                UserCredential credentials;                string dataStoreFolder = Environment.CurrentDirectory;                using (var streams = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))                {                    // create authorization code flow with clientSecrets                    GoogleAuthorizationCodeFlow authorizationCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer                    {                        DataStore = new FileDataStore(dataStoreFolder),                        ClientSecrets = GoogleClientSecrets.Load(streams).Secrets                    });                    FileDataStore fileStore = new FileDataStore(dataStoreFolder);                    TokenResponse tokenResponse = await fileStore.GetAsync<TokenResponse>(userAccount.Id.ToString());                    credentials = new UserCredential(authorizationCodeFlow, userAccount.Id.ToString(), tokenResponse);                }                var service = new YouTubeService(new BaseClientService.Initializer                {                    HttpClientInitializer = credentials,                    ApplicationName = "attnlive"                });                //Create Broadcast                string privacy = string.Empty;                if (youtubeIsPublic == true)                    privacy = "public";                else if (youtubeIsPublic == false)                    privacy = "private";                else if (youtubeIsPublic == null)                    privacy = "unlisted";                var broadcast = new LiveBroadcast                {                    Kind = "youtube#liveBroadcast",                    Snippet = new LiveBroadcastSnippet                    {                        Title = title,                        Description = description,                        ScheduledStartTime = eventStartDate                    },                    Status = new LiveBroadcastStatus                    {                        /*if(YoutubeIsPublic == true)*/                        PrivacyStatus = privacy,                        LifeCycleStatus = "ready"                    },                    ContentDetails = new LiveBroadcastContentDetails                    {                        MonitorStream = new MonitorStreamInfo                        { EnableMonitorStream = false },                        //This works instead of Transition method                        EnableAutoStart = true                    }                };                var requestLiveBroadcast = service.LiveBroadcasts.Insert(broadcast, "id,snippet,status,contentDetails");                var responseLiveBroadcast = requestLiveBroadcast.Execute();                //Create Stream                var stream = new LiveStream                {                    Kind = "youtube#liveStream",                    Snippet = new LiveStreamSnippet                    {                        Title = title,                        Description = description                    },                    Status = new LiveStreamStatus                    {                        StreamStatus = "ready"                    },                    Cdn = new CdnSettings                    {                        FrameRate = "30fps",                        IngestionType = "rtmp",                        Resolution = "1080p"                    },                    ContentDetails = new LiveStreamContentDetails                    {                        IsReusable = true                    }                };                var requestLiveStream = service.LiveStreams.Insert(stream, "snippet,cdn,contentDetails,status");                var responseLiveStream = requestLiveStream.Execute();                var ingestionAddress = responseLiveStream.Cdn.IngestionInfo.IngestionAddress;                var streamName = responseLiveStream.Cdn.IngestionInfo.StreamName;                //Bind the LiveBroadcast and Live Stream                var liveBroadcastBind = service.LiveBroadcasts.Bind(responseLiveBroadcast.Id, "id,status,contentDetails");                liveBroadcastBind.StreamId = responseLiveStream.Id;                responseLiveBroadcast = liveBroadcastBind.Execute();                var liveStreamRequest = service.LiveStreams.List("");                watchUrl = liveBroadcastBind.Id;                //Enable Fmbeg                string path = Environment.CurrentDirectory +"\\wwwroot\\images\\";                string userImagePath = "youtube.png";                if (!string.IsNullOrEmpty(userAccount.YoutubeMutexImage))                    userImagePath = userAccount.YoutubeMutexImage;                else if (!string.IsNullOrEmpty(userAccount.ImagePath))                    userImagePath = userAccount.ImagePath;                string arguments = string.Format(this.Options.StreamingYouTubeFfmpegParams, path + userImagePath, userAccount.Id, streamName);                using (var process = new Process())                {                    process.StartInfo.FileName = this.Options.StreamingYouTubeFfmpegFilePath; // relative path. absolute path works too.                    process.StartInfo.Arguments = arguments;                    process.StartInfo.CreateNoWindow = true;                    process.StartInfo.UseShellExecute = false;                    Thread.Sleep(this.Options.FfmpegStartDelay);                    process.Start();                    userAccount.YoutubeStreamingProcessId = process.Id.ToString() +"|" + responseLiveBroadcast.Id;                    await this._usersService.UpdateUserAccountAsync(userAccount);                }                //LiveBroadcast.Transition - the LiveStream Status should be active to run the step below                // Thread.Sleep(20000);                //var broadCastTransTesting                //            = service.LiveBroadcasts.Transition(                //                LiveBroadcastsResource.TransitionRequest.BroadcastStatusEnum.Testing, responseLiveBroadcast.Id, "status");                //broadCastTransTesting.Execute();                //This should be working if EnableAutoStart for broadcast is not true or does not exists at all                //LiveBroadcast.Transition - the Broadcast LifeCycleStatus should be Testing to run the step below                //Thread.Sleep(this.Options.StreamingYouTubeDelay); //miliseconds                //var broadCastTransLive                //= service.LiveBroadcasts.Transition(                //    LiveBroadcastsResource.TransitionRequest.BroadcastStatusEnum.Live, responseLiveBroadcast.Id, "status");                //broadCastTransLive.Execute();            }            catch (Exception ex)            {                return ex.Message;            }            return watchUrl;        }        public async Task<String> StopLiveBroadcastEventAsync(UserAccounts userAccount)        {            try            {                if (userAccount.YoutubeStreamingProcessId != null)                {                    string[] values = userAccount.YoutubeStreamingProcessId.Split("|");                    string encoderSoftwareProcessId = values[0];                    string youtubeBroadcastId = values[1];                    userAccount.YoutubeStreamingProcessId = null;                    await this._usersService.UpdateUserAccountAsync(userAccount);                    Process s = Process.GetProcessById(Int32.Parse(encoderSoftwareProcessId));                    if (s != null)                    {                        Thread.Sleep(this.Options.StreamingYouTubeKillDelay);                        s.Kill();                    }                    //UserCredential credentials;                    string[] scopes = new string[] { "https://www.googleapis.com/auth/youtube" }; // user basic profile                    UserCredential credentials;                    string dataStoreFolder = Environment.CurrentDirectory;                    using (var streams = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read))                    {                        // create authorization code flow with clientSecrets                        GoogleAuthorizationCodeFlow authorizationCodeFlow = new GoogleAuthorizationCodeFlow(new GoogleAuthorizationCodeFlow.Initializer                        {                            DataStore = new FileDataStore(dataStoreFolder),                            ClientSecrets = GoogleClientSecrets.Load(streams).Secrets                        });                        FileDataStore fileStore = new FileDataStore(dataStoreFolder);                        TokenResponse tokenResponse = await fileStore.GetAsync<TokenResponse>(userAccount.Id.ToString());                        credentials = new UserCredential(authorizationCodeFlow, userAccount.Id.ToString(), tokenResponse);                    }                    var service = new YouTubeService(new BaseClientService.Initializer                    {                        HttpClientInitializer = credentials,                        ApplicationName = "attnlive"                    });                    //Thread.Sleep(108000);                    var broadCastTransTesting                  = service.LiveBroadcasts.Transition(                      LiveBroadcastsResource.TransitionRequest.BroadcastStatusEnum.Complete, youtubeBroadcastId, "status");                    broadCastTransTesting.Execute();                    return youtubeBroadcastId;                }            }            catch (Exception)            {            }            return "-1";        }    }}

Viewing all articles
Browse latest Browse all 3831

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>