Play YouTube video in sync across multiple clients - javascript

Hello Stack Overflow community,
I'm a rather novice coder, but I have a project I've been devising that looks more and more complicated every day, and I don't know where to start.
With inspiration taken from Synchtube & Phonoblaster, I'm looking to create something for my website that will allow visitors to watch YouTube videos and playlists that I have curated, together in real-time, in-sync.
Because I want to be able to put this in the context of my own website, I can't use the services listed above that already do this - so I wanted to figure out how to roll my own.
Some things have been written about this topic on Stack Overflow, and other blogs:
HERE
and HERE.
Because I still consider myself a novice programmer, and a lot of the information I've found on Google and Stack tends to be more than 1 or 2 years old, I'm still unsure where to begin or if this information is outdated. Specifically, what languages and tools I should be learning.
From what I've gathered so far, things like Javascript, Node.JS, and the YouTube API would form the crux of it. I've not used any of these before, but would be interested to see whether other experienced coders would have their own suggestions or ideas they could point me towards.
I appreciate you taking time out to read this post!
Hope to hear from some of you soon :)
Many thanks.

It partially sounds like you need a live stream from Youtube. You can find more info here. https://support.google.com/youtube/bin/answer.py?hl=en&answer=2474026
If you can get that going, then syncing play between any number of users is as simple as embedding a regular youtube embed of your stream in a browser.
Looking past that, if you wanted to sync video playback amongst any number of users, the first big problem is learning how to set time on a video. Luckily, that's easy with the hashbang #t=seconds.
Eg: http://www.youtube.com/watch?v=m38RdUGqBPM&feature=g-high-rec#t=619s will start this HuskyStarcraft video at 619 seconds into the video.
The next step is to have some backend server that keeps track of what the current time is. Node.js with Socket.io is incredibly easy to get setup. Socket.io is a wonderful library that gracefully handles concurrency connections from web sockets all through long polling and more and works well even on very old browsers. Note that websockets aren't even required, but will be the most modern and full-proof method for you. Otherwise its hacks and stuff.
One way this could work would be as follows.
User1 visits your site and starts playing the video first. A script on your page sends an XHR request to your server that says, "video started at time X". X then gets stored as the start time.
At this point, you could go 2 routes. You can have a client-side script using the Youtube API to poll the video and get its current status every second. If the status or time changes, send another request back to the server to update the state.
Another simple route would be to have the page load for User2+, then send an XHR request asking for the video play time. The server sends back the difference between the start time from User1, then the client script sets the 't' hashbang on the youtube player for User2+. This lets you sync start times, but if any users pause or rewind the video, those states dont get updated. A subsequent page refresh might do that though.
The entire application complexity depends on exactly what requirements you want to have. If its just synchronized start times, then route #2 should work well enough. Doesn't require sockets and is easy to do with jQuery or just straight javascript.
If you need a really synchronized experience where any user can start/stop/pause/fast forward/rewind the video, then you're looking at either using an established library solution or writing your own.
Sorry this answer is kind of open ended, but so was your question. =)

Related

How to stream audio from a manually created audio stream? (client side)

Everything is being done in the front end.
My goal is to be able to create an audio track, in real time, and play it instantly for a user. The file would be roughly 10 minutes. However, the files are very simple, mostly silence, with a few sound clips (the sound clip is 2kb) sprinkled around. So the process for generating the data (the raw bytes) is very simple, it's either write the 2kb sound clip or place n amount of 00 for the silence. It's just that for 10 minutes. But instead of generating the entire file fully, and then playing it, I would like to stream the audio, ideally I would be generating more and more of the file while the audio was playing. It would prevent any noticeable delay between when the user clicks play and when the audio starts playing. The process of creating the file can take anywhere from 20 milliseconds to 500 milliseconds, different files are created based off user input.
The only problem is: I have no idea how to do this. I've read ideas about using web sockets, but that seems like the data would come from the server, I see no reason why to bother a server with this when the JavaScript can easily generate the audio data on its own.
I've been researching and experimenting with the Web Audio API and the Media Streams API for the past several hours, and I keep going in circles and I'm totally confused by it. I'm starting to think that these API are meant to be used for gathering data from a users mic or webcam, and not fed data directly from a readable stream.
Is what I want to do possible? Can it be achieved using something like a MediaStreamAudioSourceNode or is there another simpler way that I haven't noticed?
Any help on this topic would be so greatly appreciated. Examples of a simple working version would be even more appreciated. Thanks!
I'm going to follow this question, because a true streaming solution would be very nice to know about. My experience is limited to using WebAudio API to play to two sounds with a given pause in between them. The data is actually generated at the server and downloaded using Thymeleaf, into two javascript variables that hold the PCM data to be played. But this data could easily have been generated at the client itself via Javascript.
The following is not great, but almost could be workable, given that there are extensive silences. I'm thinking, manage an ordered FIFO queue with the variable name and some sort of timing value for when you want the associated audio played, and have a function that periodically polls the queue and loads commands into javascript setTimeout methods with the delay amount calculated based on the timing values given in the queue.
For the one limited app I have, the button calls the following (where I wrote a method that plays the sound held in the javascript variable)
playTone(pcmData1);
setTimeout(() => playTone(pcmData2), 3500);
I have the luxury of knowing that pcmData1 is 2 seconds long, and a fixed pause interval between the two sounds. I also am not counting on significant timing accuracy. For your continuous playback tool, it would just have the setTimeout part with values for the pcmData variable and the timing obtained from the scheduling FIFO queue.
Whether this is helpful and triggers a useful idea, IDK. Hopefully, someone with more experience will show us how to stream data on the fly. This is certainly something that can be easily done with Java, using it's SourceDataLine class which has useful blocking-queue aspects, but I haven't located a Javascript equivalent yet.

How to make a multiplayer javascript game cheat proof whilst considering server load

to learn some more and new techniques I've started building a little game. The idea is to keep expanding it and adding new things. It is a nice way for me to experiment and try out new techniques whilst also having something to play with.
Right now I have a base standing that works quite well. It is fully build in Vue.js. However right now everything is being handled client side. In the future I would like to use websockets to turn this into a multiplayer game. I get that it would be less than ideal to have the clients handle everything because cheating would be very easy to do. I was wondering what the best way to counter this would be. My game is somewhat like space invaders. A lot of enemies spawn and you have to shoot them.
Initially I thought of having all the game logic on a server and just have the client render things as the server dictates it to do. But how would this turn out with a high load? If 10000 players are playing at the same time this would mean an enormous amount of requests per second to the server. This would heavily impact the performance of the game I think.
What are the best practices when it comes to this? I would like to keep things as cheat proof as possible whilst also keeping a high load and well functioning game in mind. I have read that some games just use some form of obfuscation as to how a score is calculated but since mine is quite simple it seems that obfuscating it would not really work. I have included a screenshot of the current game to give you an idea of what I'm talking about.
You are the ship, the enemies are the yellow dots and spawn at the top. When they hit the bottom row you lose a life. When you lose 3 it is game over. My problem is that with many of these games running at the same time keeping track of all these enemies would become extremely difficult as there will be lots.
With kind regards.
First, TCP is not the way to go if you plan to have thousands of user to keep in sync, you have to go with UDP that is a far better protocol than TCP when dealing with multiplayer.
Second, you are right, the game engine must run also on the server and the server engine clock has to be ahead of players engine clock (maybe 200/500ms) in order to validate and forecast user input.
Then when you receive an input you can validate both the input at the time it was fired (your engine has already passed that gametime) and check the condition on the next 200/500ms making possible to reconcile the client state as needed.
Multiplayer data prevision and sync is hard take a look at the already available implementations like this or articles about this particular topic as this
Note: you'll find more help posting in https://gamedev.stackexchange.com/

How can I activate a button on a website in real time only when I specifically choose to?

this one is a bit tricky to explain, but for simplicity's sake, lets say I have a website (it doesn't have to be html or php or anything, I'm comfortable with most languages) where there are two buttons, yes or no. in order to see the buttons, you would need to have an account and login to load the page that loads the buttons (I've done this part). the buttons, for the grand majority of time, would be hidden and deactivated. However, when I somehow send a command from my computer, the buttons would become visible and the user would be able to make a choice. In this case, the transition would have to be in real time, so the user would not have to reload the page to see if the buttons are usable again. I would then be able to deactivate them again and start again.
I've been looking around the net for solutions for this for the past two days but I can't wrap my head around it. the closest I've come is to using socket.io but I think I might be overlooking another solution that I don't even know about. These commands would have to fire from unity3d, and the socket scripts made for it are outdated and difficult to get working. Am I missing something?
Web sockets support the type of functionality you are describing, but before web sockets came along, other techniques, like polling provided the appearance of getting an uninitiated message from the server. This works by essentially repeatedly asking for any changes by the server. Modern day applications that implement sockets will still fall back on polling when necessary. This would be another option to consider.
This site describes it well and this stack overflow answer give a good high level description of outdated techniques and why web sockets are the the way to go if possible...
"To overcome this deficiency, Web app developers can implement a technique called HTTP long polling, where the client polls the server requesting new information. The server holds the request open until new data is available. Once available, the server responds and sends the new information. When the client receives the new information, it immediately sends another request, and the operation is repeated. This effectively emulates a server push feature."

Synchronised data across all clients

A few weeks ago I watched a demo video of a framework that could synchronize data between clients. It showed 2 browsers that displayed a list of data. When a new item was inserted into one, it would also appear on the second.
I forgot to bookmark this website. I don't quite know the language it was written in, but I suspect node. Now I would like to investigate this mechanism of synchronizing data, but can't find this framework again.
Can anyone recall such a framework or comparable "technology"?
You probably saw this screencast of Meteor:
http://www.meteor.com/screencast
Just a wild guess :)

Will faster frequency of polling bog down my page?

So I have a Rails app (which in this case seems like it would be irrelevant, but I'll mention it anyway). It's a sort of chat room application.
In order to tell which users are currently in a chat room, I've been using Javascript polling.
So a simple
$(function() {
setTimeout(updateUsers, 15000);
});
where updateUsers just calls an AJAX get request to pull the array of users currently in the chatroom.
Here's my question: 15 seconds is a pretty long time to wait to poll. How frequently should I do it without performance issues? Obviously it depends on a lot of factors, but I'd like to hear those factors. I've seen a bunch of similar questions for receiving messages in chat rooms, but none yet for lists of users, which is why I'm asking this question.
It depends on a ton of things, like your infrastructure, the number of expected users, etc. Even if we had those numbers, it's hard to tell what would be a good timeout.
If you are only sending out a simple JSON array with the list of users, I'd say experiment with a 3-5 seconds delay and check from there. This is a problem of premature optimization- you're trying to solve a problem you don't yet have.
There are, however, two other possible solutions:
You could only send the difference. When you poll, you return a message saying which users have connected and which have left since the last polling. This requires some kind of server tracking, but can be done.
The other solution would be to not use polling at all, and use a more modern technology like WebSockets / Long-polling. Those will allow the server itself to send messages to your clients. As such, you can send them an initial list when they connect, and a single minimal message everytime someone else connects / leaves. A great solution to this in a Node environment is Socket.IO. I'm not much of a Ruby guy so I don't know if anyone has done something similar but I wouldn't be surprised if someone had ported the whole thing to Rails. Search around, I'm sure you'll find something that fits your needs.
Anything more frequent adds an additional load, albeit the server, the client or both.
Having said that, I don't think there's a "Sweet spot" (to which it appears you're referring). However, you can look in to Ruby Push API which basically keeps a connection open at all times and sends data only when necessary. (Having searched a little further, there appears to also be a Juggernaut plugin, too.)
I think you should you some comet technology
http://en.wikipedia.org/wiki/Comet_(programming))
Or add some function that look for the average response time and change the interval dynamic. Maybe the server could tell the client that "I have much to do, please wait 30 sec until next request".

Categories