File size: 5,284 Bytes
263280b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { useEffect, useRef } from 'react';

interface VideoInputProps {
  onVideoUpload: (file: File) => void;
  videoFile: File | null;
  isProcessing: boolean;
  onToggleCamera: () => void;
  cameraStream: MediaStream | null;
  previewUrl: string | null;
}

export function VideoInput({
  onVideoUpload,
  videoFile,
  isProcessing,
  onToggleCamera,
  cameraStream,
  previewUrl,
}: VideoInputProps) {
  const fileInputRef = useRef<HTMLInputElement>(null);
  const previewRef = useRef<HTMLVideoElement>(null);

  useEffect(() => {
    const video = previewRef.current;
    if (!video) return;

    if (cameraStream) {
      video.srcObject = cameraStream;
      video.muted = true;
      void video.play();
      return;
    }

    if (previewUrl) {
      video.srcObject = null;
      video.src = previewUrl;
      void video.play();
      return;
    }

    video.srcObject = null;
    video.removeAttribute('src');
    video.load();
  }, [cameraStream, previewUrl]);

  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      onVideoUpload(file);
    }
  };

  return (
    <div className="bg-white rounded-lg border border-gray-200 p-6 mb-6">
      <div className="flex items-center justify-between mb-4">
        <div>
          <h2 className="text-xl mb-1">Video Input</h2>
          <p className="text-sm text-gray-600">Upload a video or use your camera to capture sign language</p>
        </div>
        <div className="flex gap-2">
          <button 
            onClick={onToggleCamera}
            disabled={isProcessing}
            className="px-4 py-2 border border-gray-300 rounded-lg bg-white hover:bg-gray-50 flex items-center gap-2 disabled:cursor-not-allowed disabled:opacity-60"
          >
            <span>📹</span>
            Use Camera
          </button>
          <button 
            onClick={() => fileInputRef.current?.click()}
            disabled={isProcessing}
            className="px-4 py-2 bg-black text-white rounded-lg hover:bg-gray-800 flex items-center gap-2 disabled:cursor-not-allowed disabled:opacity-60"
          >
            <span></span>
            Upload Video
          </button>
          <input
            ref={fileInputRef}
            type="file"
            accept="video/*"
            onChange={handleFileChange}
            className="hidden"
          />
        </div>
      </div>

      <div className="grid grid-cols-2 gap-4">
        {/* Original Video Feed */}
        <div className="bg-gray-900 rounded-lg p-8 aspect-video flex flex-col items-center justify-center">
          {cameraStream || previewUrl ? (
            <video
              ref={previewRef}
              className="h-full w-full rounded-lg object-cover"
              playsInline
            />
          ) : (
            <>
              <div className="text-gray-600 mb-3">
                <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
                  <rect x="2" y="7" width="20" height="14" rx="2" ry="2"></rect>
                  <polyline points="23 7 16 12 23 17"></polyline>
                </svg>
              </div>
              <div className="text-gray-500 text-center">
                <div className="font-medium mb-1">Original Video Feed</div>
                <div className="text-sm">Camera inactive</div>
              </div>
            </>
          )}
          {videoFile && (
            <div className="mt-4 text-white text-sm">
              ✓ {videoFile.name}
            </div>
          )}
          <div className="mt-6 text-gray-600 text-sm">
            Duration: 00:00
          </div>
        </div>

        {/* Enhanced Video */}
        <div className="bg-gray-900 rounded-lg p-8 aspect-video flex flex-col items-center justify-center">
          <div className="text-gray-600 mb-3">
            <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
              <circle cx="12" cy="12" r="3"></circle>
              <circle cx="12" cy="12" r="10"></circle>
              <line x1="12" y1="2" x2="12" y2="4"></line>
              <line x1="12" y1="20" x2="12" y2="22"></line>
              <line x1="4.93" y1="4.93" x2="6.34" y2="6.34"></line>
              <line x1="17.66" y1="17.66" x2="19.07" y2="19.07"></line>
              <line x1="2" y1="12" x2="4" y2="12"></line>
              <line x1="20" y1="12" x2="22" y2="12"></line>
              <line x1="6.34" y1="17.66" x2="4.93" y2="19.07"></line>
              <line x1="19.07" y1="4.93" x2="17.66" y2="6.34"></line>
            </svg>
          </div>
          <div className="text-gray-500 text-center">
            <div className="font-medium mb-1">Enhanced Video</div>
            <div className="text-sm">Brightness correction applied</div>
          </div>
          <div className="mt-6 flex gap-8 text-sm">
            <div className="text-gray-600">
              Resolution: --
            </div>
            <div className="text-gray-600">
              Enhancement: Pending
            </div>
            <div className="text-gray-600">
              Quality: --
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}