Livestream Engineer Skill
I help you build live streaming features, implement WebRTC, and create real-time broadcasting experiences.
What I Do
Live Streaming:
WebRTC peer-to-peer video Live broadcasting Screen sharing Real-time chat
Streaming Platforms:
Twitch-style streaming Video conferencing Live events Webinars WebRTC Basics Peer-to-Peer Video Call // lib/webrtc.ts export class WebRTCConnection { private peerConnection: RTCPeerConnection private localStream: MediaStream | null = null
constructor() { this.peerConnection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }) }
async startLocalStream() { try { this.localStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true })
this.localStream.getTracks().forEach(track => {
this.peerConnection.addTrack(track, this.localStream!)
})
return this.localStream
} catch (error) {
console.error('Failed to get local stream:', error)
throw error
}
}
async createOffer() { const offer = await this.peerConnection.createOffer() await this.peerConnection.setLocalDescription(offer) return offer }
async handleAnswer(answer: RTCSessionDescriptionInit) { await this.peerConnection.setRemoteDescription(answer) }
async handleOffer(offer: RTCSessionDescriptionInit) { await this.peerConnection.setRemoteDescription(offer) const answer = await this.peerConnection.createAnswer() await this.peerConnection.setLocalDescription(answer) return answer }
addIceCandidate(candidate: RTCIceCandidateInit) { return this.peerConnection.addIceCandidate(candidate) }
onTrack(callback: (stream: MediaStream) => void) { this.peerConnection.ontrack = event => { callback(event.streams[0]) } }
onIceCandidate(callback: (candidate: RTCIceCandidate) => void) { this.peerConnection.onicecandidate = event => { if (event.candidate) { callback(event.candidate) } } }
close() { this.localStream?.getTracks().forEach(track => track.stop()) this.peerConnection.close() } }
Usage:
'use client' import { useEffect, useRef, useState } from 'react' import { WebRTCConnection } from '@/lib/webrtc'
export function VideoCall() {
const localVideoRef = useRef
useEffect(() => { const init = async () => { // Start local stream const stream = await connection.startLocalStream() if (localVideoRef.current) { localVideoRef.current.srcObject = stream }
// Handle remote stream
connection.onTrack((remoteStream) => {
if (remoteVideoRef.current) {
remoteVideoRef.current.srcObject = remoteStream
}
})
// Handle ICE candidates
connection.onIceCandidate((candidate) => {
// Send candidate to other peer via signaling server
socket.emit('ice-candidate', candidate)
})
}
init()
return () => {
connection.close()
}
}, [connection])
return (
You
Remote
Screen Sharing 'use client' import { useRef, useState } from 'react'
export function ScreenShare() {
const videoRef = useRef
const startSharing = async () => { try { const mediaStream = await navigator.mediaDevices.getDisplayMedia({ video: { cursor: 'always' }, audio: false })
setStream(mediaStream)
if (videoRef.current) {
videoRef.current.srcObject = mediaStream
}
setSharing(true)
// Handle when user stops sharing via browser UI
mediaStream.getVideoTracks()[0].onended = () => {
stopSharing()
}
} catch (error) {
console.error('Failed to start screen sharing:', error)
}
}
const stopSharing = () => { stream?.getTracks().forEach(track => track.stop()) setStream(null) setSharing(false) }
return (
<button
onClick={sharing ? stopSharing : startSharing}
className={`mt-4 px-6 py-3 rounded ${
sharing ? 'bg-red-600' : 'bg-blue-600'
} text-white`}
>
{sharing ? '⏹️ Stop Sharing' : '🖥️ Share Screen'}
</button>
</div>
) }
Live Streaming with Chat // components/LiveStream.tsx 'use client' import { useState, useEffect, useRef } from 'react' import { io, Socket } from 'socket.io-client'
interface ChatMessage { user: string message: string timestamp: Date }
export function LiveStream({ streamId }: { streamId: string }) {
const videoRef = useRef
useEffect(() => { // Connect to streaming server const newSocket = io('wss://streaming-server.com') setSocket(newSocket)
// Join stream room
newSocket.emit('join-stream', streamId)
// Receive viewer count
newSocket.on('viewer-count', (count: number) => {
setViewers(count)
})
// Receive chat messages
newSocket.on('chat-message', (msg: ChatMessage) => {
setMessages(prev => [...prev, msg])
})
// Receive video stream chunks (simplified)
newSocket.on('stream-data', (data: ArrayBuffer) => {
// Handle stream data
})
return () => {
newSocket.disconnect()
}
}, [streamId])
const sendMessage = () => { if (!socket || !messageInput.trim()) return
socket.emit('chat-message', {
user: 'Anonymous',
message: messageInput,
timestamp: new Date()
})
setMessageInput('')
}
return (
<div className="p-4 bg-gray-900 text-white">
<h2 className="text-xl font-bold">Live Stream Title</h2>
<p className="text-sm text-gray-400">
🔴 {viewers} watching now
</p>
</div>
</div>
</div>
{/* Chat */}
<div className="flex flex-col h-[600px]">
<div className="bg-gray-100 p-4 rounded-t-lg font-semibold">
Live Chat
</div>
<div className="flex-1 overflow-y-auto p-4 bg-white border-x">
{messages.map((msg, i) => (
<div key={i} className="mb-3">
<span className="font-semibold text-blue-600">{msg.user}:</span>
<span className="ml-2">{msg.message}</span>
</div>
))}
</div>
<div className="p-4 bg-gray-100 rounded-b-lg">
<input
type="text"
value={messageInput}
onChange={(e) => setMessageInput(e.target.value)}
onKeyPress={(e) => e.key === 'Enter' && sendMessage()}
placeholder="Say something..."
className="w-full px-4 py-2 border rounded"
/>
</div>
</div>
</div>
) }
Broadcasting Dashboard // components/BroadcastDashboard.tsx 'use client' import { useState, useRef } from 'react'
export function BroadcastDashboard() {
const videoRef = useRef
const startBroadcast = async () => { try { const mediaStream = await navigator.mediaDevices.getUserMedia({ video: { width: { ideal: 1920 }, height: { ideal: 1080 } }, audio: { echoCancellation: true, noiseSuppression: true } })
setStream(mediaStream)
if (videoRef.current) {
videoRef.current.srcObject = mediaStream
}
// Start broadcasting to server
// (Implementation depends on streaming protocol)
setBroadcasting(true)
} catch (error) {
console.error('Failed to start broadcast:', error)
}
}
const stopBroadcast = () => { stream?.getTracks().forEach(track => track.stop()) setStream(null) setBroadcasting(false) }
return (
Broadcast Dashboard
{broadcasting && (🔴 LIVE - {viewers} viewers
)} <div className="bg-black rounded-lg overflow-hidden mb-6">
<video
ref={videoRef}
autoPlay
muted
className="w-full aspect-video"
/>
</div>
<div className="flex gap-4">
<button
onClick={broadcasting ? stopBroadcast : startBroadcast}
className={`flex-1 py-3 rounded-lg font-semibold ${
broadcasting
? 'bg-red-600 text-white'
: 'bg-blue-600 text-white'
}`}
>
{broadcasting ? '⏹️ End Broadcast' : '🔴 Start Broadcast'}
</button>
{broadcasting && (
<button className="px-6 py-3 bg-gray-200 rounded-lg">
⚙️ Settings
</button>
)}
</div>
</div>
) }
Multi-Party Video Conference // components/VideoConference.tsx 'use client' import { useEffect, useState, useRef } from 'react'
interface Participant { id: string name: string stream: MediaStream }
export function VideoConference() {
const [participants, setParticipants] = useState
useEffect(() => { // Initialize local stream navigator.mediaDevices.getUserMedia({ video: true, audio: true }) .then(stream => { if (localVideoRef.current) { localVideoRef.current.srcObject = stream } }) }, [])
return (
{/* Remote participants */}
{participants.map((participant) => (
<div key={participant.id} className="relative bg-black rounded-lg overflow-hidden">
<video
autoPlay
className="w-full aspect-video object-cover"
ref={(video) => {
if (video) video.srcObject = participant.stream
}}
/>
<div className="absolute bottom-2 left-2 bg-black/70 text-white px-2 py-1 rounded text-sm">
{participant.name}
</div>
</div>
))}
</div>
<div className="mt-6 flex justify-center gap-4">
<button className="px-6 py-3 bg-red-600 text-white rounded-lg">
🎤 Mute
</button>
<button className="px-6 py-3 bg-red-600 text-white rounded-lg">
📹 Stop Video
</button>
<button className="px-6 py-3 bg-blue-600 text-white rounded-lg">
🖥️ Share Screen
</button>
<button className="px-6 py-3 bg-red-600 text-white rounded-lg">
📞 Leave Call
</button>
</div>
</div>
) }
When to Use Me
Perfect for:
Building video call features Creating livestream platforms Implementing screen sharing Building webinar tools Creating video conferencing apps
I'll help you:
Implement WebRTC Build broadcast features Add screen sharing Create video conferencing Handle real-time chat What I'll Create 🎥 Live Streaming 📹 Video Calls 🖥️ Screen Sharing 💬 Real-Time Chat 👥 Multi-Party Conferences 🔴 Broadcasting Tools
Let's build amazing live experiences!
← 返回排行榜