import ffmpeg
import threading
import http.server
import socketserver
import pychromecast
import time
import platform
import os
import sys

# HTTP server to serve the stream
class StreamHandler(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "video/mp4")
        self.end_headers()
        try:
            with open("stream.mp4", "rb") as f:
                self.wfile.write(f.read())
        except FileNotFoundError:
            self.send_error(404, "Stream not ready")

def http_and_chromecast_thread():
    # Start HTTP server
    port = 8000
    server = socketserver.TCPServer(("", port), StreamHandler)
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    print(f"HTTP server running on http://localhost:{port}")

    # Initialize Chromecast
    chromecasts, browser = pychromecast.get_listed_chromecasts(friendly_names=["Living Room"])  # Replace with your Chromecast name
    if not chromecasts:
        print("No Chromecast found")
        return
    cast = chromecasts[0]
    cast.wait()
    print(f"Connected to Chromecast: {cast.device.friendly_name}")

    # Play stream
    mc = cast.media_controller
    stream_url = f"http://localhost:{port}/stream.mp4"
    mc.play_media(stream_url, "video/mp4")
    mc.block_until_active()

    # Keep thread alive
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        mc.stop()
        cast.quit_app()
        pychromecast.discovery.stop_discovery(browser)
        server.shutdown()
        server.server_close()

def ffmpeg_capture_thread():
    system = platform.system()
    output_file = "stream.mp4"

    while True:
        try:
            # Video input (platform-specific)
            if system == "Linux":
                video = ffmpeg.input(":0.0+0,0", format="x11grab", s="1280x720")
            elif system == "Windows":
                video = ffmpeg.input("desktop", format="gdigrab", s="1280x720")
            elif system == "Darwin":  # macOS
                video = ffmpeg.input("1:none", format="avfoundation", capture_cursor=1, s="1280x720")
            else:
                print(f"Unsupported platform: {system}")
                return

            # Audio input (platform-specific)
            audio = None
            if system == "Linux":
                try:
                    # Try PulseAudio first
                    audio = ffmpeg.input("default", format="pulse")
                except Exception:
                    print("PulseAudio failed, falling back to ALSA")
                    audio = ffmpeg.input("hw:0", format="alsa")  # Adjust device if needed
            elif system == "Windows":
                audio = ffmpeg.input("audio=Stereo Mix", format="dshow")  # Adjust to your audio device
            elif system == "Darwin":
                audio = ffmpeg.input("0", format="avfoundation")  # Adjust to BlackHole or microphone

            # Combine video and audio streams
            stream = ffmpeg.output(
                video, audio, output_file, format="mp4", vcodec="libx264", acodec="aac",
                pix_fmt="yuv420p", r=15, preset="ultrafast", tune="zerolatency",
                movflags="frag_keyframe+empty_moov", ac=2, ar=44100
            )
            stream = ffmpeg.overwrite_output(stream)

            # Run FFmpeg
            process = stream.run_async()
            process.wait()
            print("FFmpeg stopped unexpectedly")
        except Exception as e:
            print(f"FFmpeg error: {e}")
        finally:
            if os.path.exists(output_file):
                os.remove(output_file)  # Clean up before restart
            print("Restarting FFmpeg in 5 seconds...")
            time.sleep(5)

def main():
    # Start HTTP server and Chromecast thread
    threading.Thread(target=http_and_chromecast_thread, daemon=True).start()

    # Start FFmpeg capture thread
    threading.Thread(target=ffmpeg_capture_thread, daemon=True).start()

    # Main thread: empty loop
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        print("Exiting...")
        sys.exit(0)

if __name__ == "__main__":
    main()
