As a reminder, I had just watched the movie Hackers and was in search of more nostalgia. So I scrubbed through the movie and found a fun scene where two hackers battle for control over a T.V. station.
As a reminder, I had just watched the movie Hackers and was in search of more nostalgia. So I scrubbed through the movie and found a fun scene where two hackers battle for control over a T.V. station. So I thought I would try to recreate it in the form of an interactive website. I wanted the interaction to be kind of like using the command line in a terminal. That was a little tricky but I eventually got it working. There are still some features I would like to work out, like video synchronization when a user scrubs the video, as well as pausing and resuming play, streaming your own video, and usernames. I also tried to format the page using CSS, something I haven’t really put much time into in the past.
The clip at the right is the scene from the movie that inspired this project. The code for the project is below.
HTML
<html> <head> <link rel="stylesheet" href="style.css"> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript"> let videoArr = ["YourName.mp4", "TheWall.mp4", "2001ASpace Odyssey.mp4", "SevenSamurai.mp4", "HeavyMetal.mp4", "Hackers.m4v", "GhostInTheShell.mp4", "FantasticPlanet.m4v", "Alien.m4v", "Akira.mp4", "AdriftInTheOcean.mp4", ] var socket = io.connect(); socket.on('connect', function() { console.log("Connected"); // Once we are connected, request the history socket.emit('history', null); }); // Receive from any event socket.on('chatmessage', function (data) { document.getElementById('messages').innerHTML = "" + data + "\n<br />" + "" + document.getElementById('messages').innerHTML; if(videoArr.includes(data)){ let myVideo = document.querySelector("video") myVideo.src = data; myVideo.load(); myVideo.play(); console.log(data) } }); var sendmessage = function(message) { if(message === "ls"){ videoArr.forEach((item) => { document.getElementById('messages').innerHTML = "" + '<span style="background: white;">' + item + "</span>" + "\n<br />" + "" + document.getElementById('messages').innerHTML; }) } console.log("chatmessage: " + message); socket.emit('chatmessage', message); debugger; }; </script> <style> #messages{ color: rgb(16, 139, 37); } #instructions{ color:rgb(16, 139, 37) } </style> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>ITP TV</title> </head> <body> <div id="main"> <div id="video-container"> <video id="video" width="720" height="480" autoplay muted controls> <source id="video-player" src="AdriftInTheOcean.mp4" type="video/mp4"> Your browser does not support the video tag. </video> </div> <div id="instructions"> Type: LS, for available files<br> Type: filename, to play video </div> <div id="input-box"> <input type="text" id="message" name="message" value=" "> <input id="submit-button" type="submit" value="submit" onclick="sendmessage(document.getElementById('message').value)"> <script> let input = document.getElementById("message"); input.addEventListener('keypress', (event) => { if(event.key === "Enter"){ event.preventDefault(); document.getElementById('submit-button').click() document.getElementById("message").value = ""; } }) </script> </div> <div id="messages"> mess with the best, die like the rest </div> </div> </body> </html>
JAVASCRIPT
// Database to store data var Datastore = require('nedb'); var db = new Datastore({filename: "data.db", autoload: true}); const express = require("express"); const app = express(); const path = require('path'); var http = require('http'); var fs = require('fs'); // HTTP Portion var httpServer = http.createServer(app); const { Server } = require('socket.io'); const io = new Server(httpServer, {}); httpServer.listen(8070); function requestHandler(req, res) { // Read index.html fs.readFile(__dirname + '/index.html', // Callback function for reading function (err, data) { // if there is an error if (err) { res.writeHead(500); return res.end('Error loading index.html'); } // Otherwise, send the data, the contents of the file res.writeHead(200); res.end(data); } ); } app.use('/', express.static(path.join(__dirname, 'public'))); // Register a callback function to run when we have an individual connection // This is run for each individual user that connects io.sockets.on('connection', // We are given a websocket object in our function function (socket) { console.log("We have a new client: " + socket.id) // When this user emits, client side: socket.emit('otherevent',some data); socket.on('chatmessage', function(data) { // Data comes in as whatever was sent, including objects console.log("Received: 'chatmessage' " + data); // Create the JavaScript Object var datatosave = { socketid: socket.id, message: data } // Insert the data into the database db.insert(datatosave, function (err, newDocs) { console.log("err: " + err); console.log("newDocs: " + newDocs); }); // Send it to all of the clients io.sockets.emit('chatmessage',data); }); // When the history is requested, find all of the docs in the database socket.on('history', function() { db.find({}, function(err, docs) { // Loop through the results, send each one as if it were a new chat message for (var i = 0; i < docs.length; i++) { socket.emit('chatmessage', docs[i].message); } }) }); socket.on('disconnect', function() { console.log("Client has disconnected " + socket.id); }); } );
CSS
body { background-color: black; font-family: "Helvetica", "sans-serif"; /*font-family: "Droid Sans Mono", "Courier New", monospace;*/ /* font-family: "Lucida Console", "Courier New", monospace;*/ } #video-container { float: right; width: 640px; padding-top: 2%; padding-left: 10px; padding-right: 150px; border: dashed; margin: 2px; } #instructions{ position: relative; width: 20%; margin-left: 10%; padding-top: 2%; padding-bottom: 2%; padding-left: 2%; border-style: dashed; } #input-box{ position: relative; top: 10px; padding-left: 10%; padding-top: 1%; padding-bottom: 1%; } #messages{ position: relative; top: 30px; width: 20%; margin-left: 10%; padding-left: 2%; padding-top: 1%; padding-bottom: 1%; height: 300px; overflow: auto; border: dashed; } input[type=submit] { background-color: black; border: 2px dashed; color: green; padding: 10px 20px; text-decoration: none; margin: 4px 2px; cursor: pointer; font-family: inherit; } input[type=text] { border: 2px dashed green; background-color: black; color: green; outline: none; padding: 10px 20px; font-family: inherit } input[type=text]:focus { border: 3px solid green; padding: 10px 20px; font-family: inherit }