MCPInstall

livestream-engineer

Expert in live streaming, WebRTC, and real-time video/audio

Installs
209
Last 24h
—
Trending rank
—
Security
Not audited

Install

Works with every agent the skills CLI supports.

npx skills add https://github.com/daffy0208/ai-dev-standards --skill livestream-engineer
  1. 01

    Install

    Run the command in your project. The CLI asks which agents to install for.

  2. 02

    Describe the task

    Ask your agent for something this skill covers. It loads livestream-engineer automatically when relevant.

  3. 03

    Review the result

    The agent follows the SKILL.md steps, scripts and references bundled with the skill.

SKILL.md

The instructions your agent reads when the skill is triggered.

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<HTMLVideoElement>(null)
  const remoteVideoRef = useRef<HTMLVideoElement>(null)
  const [connection] = useState(() => new WebRTCConnection())

  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 (
    <div className="grid grid-cols-2 gap-4">
      <div>
        <h3>You</h3>
        <video ref={localVideoRef} autoPlay muted className="w-full" />
      </div>
      <div>
        <h3>Remote</h3>
        <video ref={remoteVideoRef} autoPlay className="w-full" />
      </div>
    </div>
  )
}

Screen Sharing

'use client'
import { useRef, useState } from 'react'

export function ScreenShare() {
  const videoRef = useRef<HTMLVideoElement>(null)
  const [sharing, setSharing] = useState(false)
  const [stream, setStream] = useState<MediaStream | null>(null)

  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 (
    <div>
      <video ref={videoRef} autoPlay className="w-full bg-black rounded" />

      <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<HTMLVideoElement>(null)
  const [socket, setSocket] = useState<Socket | null>(null)
  const [messages, setMessages] = useState<ChatMessage[]>([])
  const [messageInput, setMessageInput] = useState('')
  const [viewers, setViewers] = useState(0)

  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="grid md:grid-cols-3 gap-4">
      {/* Video Player */}
      <div className="md:col-span-2">
        <div className="bg-black rounded-lg overflow-hidden">
          <video
            ref={videoRef}
            autoPlay
            controls
            className="w-full aspect-video"
          />

          <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<HTMLVideoElement>(null)
  const [broadcasting, setBroadcasting] = useState(false)
  const [stream, setStream] = useState<MediaStream | null>(null)
  const [viewers, setViewers] = useState(0)

  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 (
    <div className="max-w-4xl mx-auto p-6">
      <div className="mb-6">
        <h1 className="text-3xl font-bold">Broadcast Dashboard</h1>
        {broadcasting && (
          <p className="text-green-600 font-semibold mt-2">
            🔴 LIVE - {viewers} viewers
          </p>
        )}
      </div>

      <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<Participant[]>([])
  const localVideoRef = useRef<HTMLVideoElement>(null)

  useEffect(() => {
    // Initialize local stream
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
      .then(stream => {
        if (localVideoRef.current) {
          localVideoRef.current.srcObject = stream
        }
      })
  }, [])

  return (
    <div className="p-6">
      <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
        {/* Local video */}
        <div className="relative bg-black rounded-lg overflow-hidden">
          <video
            ref={localVideoRef}
            autoPlay
            muted
            className="w-full aspect-video object-cover"
          />
          <div className="absolute bottom-2 left-2 bg-black/70 text-white px-2 py-1 rounded text-sm">
            You
          </div>
        </div>

        {/* 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!

FAQ

What does the livestream-engineer skill do?

Expert in live streaming, WebRTC, and real-time video/audio

How do I install livestream-engineer?

Run npx skills add https://github.com/daffy0208/ai-dev-standards --skill livestream-engineer in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/livestream-engineer/ (personal) or .claude/skills/livestream-engineer/ (project).

Which AI agents can use livestream-engineer?

Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.

Is livestream-engineer safe to install?

No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.

Who maintains livestream-engineer?

It is published by daffy0208 in daffy0208/ai-dev-standards. It has 209 recorded installs.

More from daffy0208/ai-dev-standards

View all →

animation-designer

daffy0208/ai-dev-standards

Expert in web animations, transitions, and motion design using Framer Motion and CSS

Frontend & Design1.9K installs

brand-designer

daffy0208/ai-dev-standards

Expert in brand identity, logo design, and visual brand systems

Marketing & SEO1.3K installs

3d-visualizer

daffy0208/ai-dev-standards

Expert in Three.js, 3D graphics, and interactive 3D visualizations

Media & Creative665 installs

data-visualizer

daffy0208/ai-dev-standards

Expert in creating charts, dashboards, and data visualizations using modern libraries

572 installs

video-producer

daffy0208/ai-dev-standards

Expert in video playback, streaming, and video player customization

Media & Creative449 installs

knowledge base manager

daffy0208/ai-dev-standards

Open the skill to read its SKILL.md instructions.

438 installs

Popular media & creative skills

View category →

hyperframes

heygen-com/hyperframes

Read first to make, edit, animate or render any video with HyperFrames (HTML rendered to video), including launch films, explainers, music videos, charts, maps, vertical clips, title cards, captions and overlays. Holds the render contract, the work loop and what each kind of video needs.

Media & Creative1.2M installs

media-use

heygen-com/hyperframes

Get or make any media for a HyperFrames video - music, sound effects, images, icons, logos, voiceover, avatar and generated video, transcripts, cutouts, colour grades and looks - with HeyGen or free local tools, and mix placed audio. Also for footage that looks dark, flat or dull, or should be stylized or hidden.

Media & Creative1.1M installs

hyperframes-registry

heygen-com/hyperframes

About 450 ready-made HyperFrames blocks and components installed as editable source - transitions, overlays, titles, kinetic type, captions, charts, map overlays, 3D, camera moves. Use it before hand-building any named visual (CRT scanlines, glitch, film grain, a chart); also for hyperframes add and catalog.

Media & Creative1M installs

hyperframes-creative

heygen-com/hyperframes

Non-animation creative direction for HyperFrames videos. Use for design spec (frame.md / design.md) handling, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns, and brand / style decisions. For atomic motion patterns and scene blueprints, use hyperframes-animation.

Media & Creative916.5K installs

ai-video-generation

101-skills/superpowers

Generate AI videos with Google Veo, Seedance 2.0, HappyHorse, Wan, Grok and 40+ models via inference.sh CLI. Models: Veo 3.1, Veo 3, Seedance 2.0, HappyHorse 1.0, Wan 2.5, Grok Imagine Video, OmniHuman, Fabric, HunyuanVideo. Capabilities: text-to-video, image-to-video, reference-to-video, video editing, lipsync, avatar animation, video upscaling, foley sound. Use for: social media videos, marketing content, explainer videos, product demos, AI avatars. Triggers: video generation, ai video, text to video, image to video, veo, animate image, video from image, ai animation, video generator, generate video, t2v, i2v, ai video maker, create video with ai, runway alternative, pika alternative, sora alternative, kling alternative, seedance, happyhorse

Media & Creative881.5K installs

ai-image-generation

101-skills/superpowers

Generate AI images with GPT-Image-2, FLUX, Gemini, Grok, Seedream, Reve and 50+ models via inference.sh CLI. Models: GPT-Image-2, FLUX Dev LoRA, FLUX.2 Klein LoRA, Gemini 3 Pro Image, Grok Imagine, Seedream 4.5, Reve, ImagineArt. Capabilities: text-to-image, image-to-image, inpainting, LoRA, image editing, upscaling, text rendering. Use for: AI art, product mockups, concept art, social media graphics, marketing visuals, illustrations. Triggers: flux, image generation, ai image, text to image, stable diffusion, generate image, ai art, midjourney alternative, dall-e alternative, text2img, t2i, image generator, ai picture, create image with ai, generative ai, ai illustration, grok image, gemini image, gpt image, openai image, chatgpt image

Media & Creative880.3K installs