Xây dựng web call video cơ bản với WebRTC [P3]

6 min read

Trong phần 1 và phần 2 của series này, chúng ta đã thiết lập được một ứng dụng video call cơ bản sử dụng WebRTC, Socket.io làm signaling server, và tích hợp các kết nối giữa các peer. Tuy nhiên, để một tính năng video call thực sự hiệu quả, trải nghiệm người dùng và hiệu suất ứng dụng cần phải được tối ưu hóa.

Trong bài viết cuối cùng của series, chúng ta sẽ tập trung vào việc nâng cao trải nghiệm người dùng và tối ưu hóa hiệu năng cho ứng dụng. Bạn sẽ học cách thêm các tính năng nâng cao như chia sẻ màn hình, bật/tắt camera, và tắt tiếng micro. Đồng thời, chúng ta cũng sẽ tìm hiểu cách tối ưu băng thông, giảm độ trễ, và quản lý trạng thái kết nối mạng để đảm bảo ứng dụng hoạt động mượt mà.

web-rtc

1. Thêm tính năng nâng cao cho video call

Để tăng trải nghiệm người dùng, một số tính năng thông dụng trong các ứng dụng video call như bật/tắt camera, chia sẻ màn hình, và tắt tiếng micro sẽ giúp người dùng có nhiều sự linh hoạt hơn trong quá trình gọi.

1.1. Bật/tắt camera và tắt tiếng micro

Trong các ứng dụng video call, khả năng bật/tắt camera và micro là rất quan trọng. Chúng ta có thể dễ dàng thêm các tính năng này vào giao diện bằng cách điều chỉnh stream video và audio.

Cập nhật component VideoCall.js
export default function VideoCall() {
  const [stream, setStream] = useState(null);
  const [isCameraOn, setCameraOn] = useState(true);
  const [isMuted, setMuted] = useState(false);
  const userVideo = useRef();

  useEffect(() => {
    // Lấy luồng video/âm thanh từ camera
    navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then((stream) => {
      setStream(stream);
      if (userVideo.current) {
        userVideo.current.srcObject = stream;
      }
    });
  }, []);

  const toggleCamera = () => {
    setCameraOn(!isCameraOn);
    stream.getVideoTracks()[0].enabled = !isCameraOn; // Tắt/bật camera
  };

  const toggleMute = () => {
    setMuted(!isMuted);
    stream.getAudioTracks()[0].enabled = !isMuted; // Tắt/bật micro
  };

  return (
    <div>
      <video playsInline muted ref={userVideo} autoPlay style={{ width: '300px' }} />
      <div>
        <button onClick={toggleCamera}>
          {isCameraOn ? 'Tắt Camera' : 'Bật Camera'}
        </button>
        <button onClick={toggleMute}>
          {isMuted ? 'Bật Micro' : 'Tắt Micro'}
        </button>
      </div>
    </div>
  );
}
Giải thích mã nguồn:
  • getVideoTracks()getAudioTracks(): Được sử dụng để truy cập các track video và âm thanh trong stream.
  • .enabled: Thuộc tính này cho phép bạn bật/tắt stream của từng track. Ví dụ, khi enabled = false, camera hoặc micro sẽ bị tắt.

1.2. Chia sẻ màn hình

Chia sẻ màn hình là một tính năng phổ biến trong các cuộc họp hoặc video call chuyên nghiệp. Với WebRTC, tính năng này có thể dễ dàng thêm vào bằng cách sử dụng navigator.mediaDevices.getDisplayMedia().

Thêm tính năng chia sẻ màn hình
const shareScreen = () => {
  navigator.mediaDevices.getDisplayMedia({ video: true }).then((screenStream) => {
    const screenTrack = screenStream.getVideoTracks()[0];
    // Thay thế track video của người dùng bằng track chia sẻ màn hình
    peer.replaceTrack(stream.getVideoTracks()[0], screenTrack, stream);
    screenTrack.onended = () => {
      // Khi người dùng dừng chia sẻ màn hình, trả lại video camera
      peer.replaceTrack(screenTrack, stream.getVideoTracks()[0], stream);
    };
  });
};
Giải thích mã nguồn:
  • getDisplayMedia(): API này yêu cầu quyền truy cập và chia sẻ màn hình của người dùng.
  • replaceTrack(): Được sử dụng để thay thế track video hiện tại của WebRTC bằng track chia sẻ màn hình.

2. Tối ưu hóa băng thông và hiệu năng

Hiệu năng là yếu tố quan trọng trong các ứng dụng video call, đặc biệt khi kết nối mạng kém có thể ảnh hưởng đến chất lượng video và âm thanh. Dưới đây là một số cách tối ưu hóa băng thông và giảm độ trễ cho ứng dụng.

2.1. Tối ưu hóa băng thông video

WebRTC cho phép bạn điều chỉnh chất lượng video để tiết kiệm băng thông và tăng tốc độ kết nối. Bằng cách giới hạn độ phân giải và bitrate, chúng ta có thể đảm bảo rằng video call vẫn hoạt động ổn định ngay cả trong điều kiện mạng yếu.

Giới hạn độ phân giải và bitrate
navigator.mediaDevices.getUserMedia({
  video: {
    width: { max: 1280 },
    height: { max: 720 },
    frameRate: { max: 30 }
  },
  audio: true
}).then((stream) => {
  setStream(stream);
});
Giải thích mã nguồn:
  • widthheight: Giới hạn độ phân giải video. Ở đây, chúng ta giới hạn video ở chất lượng HD (1280×720).
  • frameRate: Giới hạn số khung hình mỗi giây, giúp giảm tải xử lý cho máy tính và tiết kiệm băng thông.

2.2. Quản lý trạng thái kết nối và xử lý lỗi

Trong các ứng dụng video call, việc xử lý các sự cố mạng như mất kết nối hoặc độ trễ cao là rất quan trọng để duy trì trải nghiệm người dùng tốt. Bạn có thể sử dụng các sự kiện WebRTC để theo dõi trạng thái kết nối và hiển thị thông báo lỗi hoặc thử kết nối lại khi cần thiết.

Theo dõi trạng thái kết nối
peer.on('iceConnectionStateChange', () => {
  const connectionState = peer.iceConnectionState;
  if (connectionState === 'disconnected' || connectionState === 'failed') {
    alert('Kết nối bị gián đoạn, vui lòng thử lại.');
  }
});
Giải thích mã nguồn:
  • iceConnectionStateChange: Được kích hoạt khi trạng thái kết nối ICE thay đổi. Dựa vào trạng thái, chúng ta có thể hiển thị thông báo cho người dùng nếu kết nối bị gián đoạn hoặc thất bại.

3. Tối ưu hóa trải nghiệm người dùng

Ngoài việc tối ưu hóa hiệu năng kỹ thuật, việc nâng cao trải nghiệm người dùng (UX) cũng quan trọng không kém. Một số cải tiến về giao diện người dùng có thể làm cho trải nghiệm gọi video trở nên mượt mà và dễ sử dụng hơn.

3.1. Hiển thị thông báo kết nối

Việc cung cấp thông tin về trạng thái kết nối và chất lượng video giúp người dùng dễ dàng theo dõi và điều chỉnh trải nghiệm video call của họ. Bạn có thể thêm các thông báo hoặc biểu tượng trạng thái (ví dụ: tín hiệu mạnh/yếu, chất lượng video cao/thấp).

peer.on('iceConnectionStateChange', () => {
  const connectionState = peer.iceConnectionState;
  if (connectionState === 'connected') {
    setConnectionStatus('Kết nối ổn định');
  } else if (connectionState === 'disconnected') {
    setConnectionStatus('Kết nối bị gián đoạn');
  }
});

3.2. Thiết kế giao diện người dùng

Tối ưu hóa giao diện video call sao cho trực quan và dễ sử dụng. Bạn có thể bổ sung các icon cho các chức năng như bật/tắt camera, tắt tiếng, chia sẻ màn hình, và đặt chúng ở những vị trí dễ truy cập.


4. Kết luận

Chúng ta đã hoàn thiện tính năng video call với nhiều cải tiến giúp nâng cao trải nghiệm người dùng, bao gồm bật/tắt camera, chia sẻ màn hình, và tắt tiếng micro. Đồng thời, bạn cũng đã học cách tối ưu hóa băng thông và hiệu suất để ứng dụng hoạt động mượt mà ngay cả khi kết nối mạng không tốt.

Với những tối ưu và tính năng nâng cao này, bạn đã có trong tay một ứng dụng video call đầy đủ và mạnh mẽ, sẵn sàng triển khai và đưa vào sử dụng trong thực tế.

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *