Chụp hình từ webcam, lưu về server sử dụng Flex và Red 5

Đây là bài hướng dẫn làm thế nào lưu hình ảnh webcam từ Flex lên  Red5 server.

Công việc của chúng ta là làm sao lấy được snapshot của video stream từ client và làm sao để lưu được image lên phía server. Có nhiều cách làm được điều này như là sử dụng ffmpeg hoặc là sử dụng một ngôn ngữ nào đó kết hợp với Red5. Nhưng có một cách cực kỳ đơn giản, chúng ta ko cần sử dụng thêm bất cứ thư viện ngoài nào khác.

Chúng ta có thể lưu hình loại PNG hoặc là JPEG tùy theo ý chúng ta.

Phía client (Flex)

Chúng ta phải có NetConnection kết nối đến Red5(Server-Side). Chúng ta cũng phải có camera được cắm vào máy và được attached vào UI component trong trình duyệt. Chúng ta có một cái nút trên ứng dụng phía client. Chúng ta gọi cái nút đó là “Take a snapshot image”. Khi chúng ta click lên cái nút đó, hàm “handleScreenShot” sẽ được gọi.

Chú ý: SharedVideo phải là một biến public thuộc lớp Video. Khi chúng ta attached video từ the camera vào UI, chúng ta copy nó vào Shared video.

private function handleScreenShot():void 
{
  // Clear out any previous snapshots
  pnlSnapshot.removeAllChildren();
  var snapshotHolder:UIComponent = new UIComponent();
  var snapshot:BitmapData = new BitmapData(320, 240, true);
  var snapshotbitmap:Bitmap = new Bitmap(snapshot);
  snapshotHolder.addChild(snapshotbitmap);
  pnlSnapshot.addChild(snapshotHolder);
  snapshot.draw(SharedVideo);
  pnlSnapshot.visible = true;
  // Encode to png or jpeg ByteArray and send it to the  server
  //var jpgEncoder:JPEGEncoder = new JPEGEncoder(75);
  //var jpgBytes:ByteArray = jpgEncoder.encode(snapshot);
  var pngEncoder:PNGEncoder = new PNGEncoder();
  var pngBytes:ByteArray = pngEncoder.encode(snapshot);
  nc.call("Save_ScreenShot", null, pngBytes);
}

Phía server (Red5)
OK. Bây giờ phía server code (ở đây code dùng ngôn ngữ Java bạn nhé, vì red5 được viết bằng ngôn ngữ Java), chúng ta có một hàm “Save_ScreenShot”.

Chú ý: phải import các class sau:

import org.red5.io.amf3.ByteArray;
import javax.imageio.ImageIO;
import java.io.ByteArrayInputStream;
import java.awt.image.BufferedImage;
public String Save_ScreenShot(ByteArray _RAWBitmapImage){
  // Use functionality in org.red5.io.amf3.ByteArray to get parameters of the ByteArray
  int BCurrentlyAvailable = _RAWBitmapImage.bytesAvailable();
  int BWholeSize = _RAWBitmapImage.length(); // Put the Red5 ByteArray into a standard Java array of bytes
  byte c[] = new byte[BWholeSize];
  _RAWBitmapImage.readBytes(c);
  // Transform the byte array into a java buffered image
  ByteArrayInputStream db = new ByteArrayInputStream(c);
  if(BCurrentlyAvailable > 0){
    System.out.println(“The byte Array currently has ” + BCurrentlyAvailable + ” bytes. The Buffer has ” +  db.available());
    try{
      BufferedImage JavaImage = ImageIO.read(db);
      // Now lets try and write the buffered image out to a file
      if(JavaImage != null) 
      {
        // If you sent a jpeg to the server, just change PNG to JPEG and Red5ScreenShot.png to .jpeg
        ImageIO.write(JavaImage, "PNG", new File("Red5ScreenShot.png"));
      }
    }
    catch(IOException e){
      log.info("Save_ScreenShot: Writing of screenshot failed " + e); System.out.println(“IO Error ” + e);
    }
  }
  return "End of save screen shot";
}

Bạn cũng có thể dùng cách này để làm được chuyện khác, ví dụ như lấy những tấm hình từ phái server về cho client.

Cám ơn Charles Palen đã post những dòng code này ở Red5 community
Enjoy coding :D


18 comments

  1. Chào các bạn !
    Sau một thời gian tìm hiểu về Red5 và flex mình đã thực hiện 1 dự án Live streaming video bước đầu cũng đã thực hiện được việc truyền hình ảnh và âm thanh , mình muốn đưa dự án qua máy khác test thử . Bạn nào đã làm đóng gói dữ liệu trong flex xin chia sẻ . Thank!

    1. Lần đầu biết được việc đóng gói trong Flex. Có gì hay bạn share với Góc Kinh Nghiệm nha :D

  2. khi thực hiện live streaming bẳng flex và record thì định dạng của nó là file .flv sau đó mình chuyển sang định dạng .mp4 nhưng bị lổi :
    NetStream.publish(“mp4:video.mp4”, “record”);
    from flex,it will be get NetStream.Record.NoAccess error.
    Bạn nào gặp rùi xin giúp đỡ . Thaks!

  3. Tới giờ thì Red5 chỉ record theo .flv thui , chưa hỗ trợ record theo các chuẩn h.264 . Trong lý thuyết flex cho phép lưu theo một vài định dạng nhưng còn tùy thuộc vào server có hỗ trợ hay không . Nếu muốn tăng chất lượng hình ảnh dùng tới phương thức sau :
    var bandwidth:int = 0;
    var quality:int = 150;
    camera.setQuality(bandwidth, quality);
    Lúc này chất lượng hình ảnh sẽ tăng rõ nét . Tiện cho mình hỏi mình có 2 camera giờ mình muốn chọn 1 cái để sử dụng vậy trong combobox mình viết như thế nào ? Ai làm rùi xin hướng dẫn nha .thaks !

  4. Thaks khanh hung !
    mình làm được rùi code :
    private function camera_microphone_start():void
    {
    if (combobox_camera.selectedIndex == -1 )
    {
    trace(“You need a webcam”);
    Alert.show(“plese select to webcam”,”Information”);
    }
    else
    {
    var bandwidth:int = 0;
    var quality:int = 150;
    trace(“You have a webcam.”);
    camera = Camera.getCamera( String(combobox_camera.selectedIndex) );
    camera.setQuality(bandwidth, quality);
    vcLocal.attachCamera(camera);
    nspublish= new NetStream(nc);
    nspublish.attachCamera(camera);
    nspublish.publish(txt_stream.text,type_save);// luu video tren server
    bt_Send.enabled=true;

    }
    }

  5. Bạn nào đã nghiên cứu cách mã hóa video dạng MPEG-4/h264 trong việc live streaming ? .
    Đối với máy chủ Red5 thì việc lưu file theo định dạng .mp4 và f4v là không thể bởi vậy dùng MPEG-4/h264 là việc khó thực hiện nếu không dùng tới tools hỗ trợ . Mình có biết chương trình Adobe Flash Media Live Encoder 3.1 họ mã hóa video theo các dạng h.264 và vp6 hình ảnh nhận được rất tốt và thực hiện luôn việc lưu trữ . Bạn nào đã tìm hiểu ứng dụng MPEG-4/h.264 trong việc truyền video xin chia sẻ . Cảm ơn !

    1. Mình cũng không biết cái này. Nhưng theo thông tin mình đọc từ trang web của Adobe thì Adobe Flash Media Live Encoder 3.1 mình sẽ sử dụng chung với Flash Media Server. Chắc dạng add-on or plug-in (theo mình đoán)

      Sau khi bạn cài đặt Flash Media Server thì (theo mình đoán) bạn cài Adobe Flash Media Live Encoder 3.1 để chuyển đổi theo định dạng bạn muốn.

      Ok! Bạn có thể remove Red5 và cài đặt sử dụng Flash Media Server cho cùng mục đích xây dựng ứng dụng Live streaming video của bạn. Flash Media Server cũng giống như Red5 nhưng Red5 thì FREE còn Flash Media Server có giá khoảng 1000$ :D

      Chúc bạn may mắn và tìm được giải pháp phù hợp :)

      Tìm được gì hay hãy chia sẽ với Góc Kinh Nghiệm bạn nhé :)

      1. Dùng Adobe Flash Media Live Encoder 3.1 kết nối tới Red5 hoàn toàn làm được . Khi đó Adobe Flash Media Live Encoder 3.1 sẽ là đầu phát và dùng bản Demo có tên Publish có sẵn của Red5 để nhận Stream chất lượng hình ảnh tốt , mình đã làm rùi . Nếu làm ứng dụng triễn khai thì xong rùi nhưng mình làm báo cáo nên phải làm ứng dụng riêng do đó phải đi code huhu :((.

  6. Khánh Hưng cho mình hỏi khi viet xong 1 dự án flash builder mình muốn chuyển qua máy khác mà không cần cài ứng dụng flash builder vẫn chạy được thì mình làm như thế nào ?
    Mình đã dùng những file biên dịch để chạy mà không chạy được , mình chưa hiểu tại sao nữa .

  7. Mình đã debug chạy bình thường lúc này vẫn còn nằm trong flash builder . Nhưng khi mang ra khỏi flash builder mình vào folder bin-debug/Red5Design.html chạy file Red5Design.html nên thì không hiện thị gì cả .
    Trong visual studio khi mình làm xong 1 dự án để chạy độc lập không dính tới visual studio thì mình phải đóng gói bộ cài đặt rùi mang tới máy khác cài mới chạy được . Trong flash builder mình cũng nghĩ như vậy , không biết thực hiện nó như thế nào ?

  8. Bạn thử check đã copy file flash chưa, nếu đã có thì bạn check xem đường dẫn đến file flash đúng chưa, nếu đúng rồi, check xem add MIME Type cho IIS chưa

  9. Chào Khánh Hưng!
    Bạn cho mình hỏi khi mình play 1 video trong flex thông qua lệnh : nsplay.play(txt_stream.text); .
    Giờ mình muốn lấy danh sách các stream name để thực hiện việc play(stream name) .
    Bạn biết xin hướng dẫn. Cảm ơn!

Leave a Reply

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