Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] export racing bar animation as video #724

Open
tyn1998 opened this issue Aug 26, 2023 · 11 comments · May be fixed by #743
Open

[Feature] export racing bar animation as video #724

tyn1998 opened this issue Aug 26, 2023 · 11 comments · May be fixed by #743
Assignees
Labels
kind/feature Category issues or prs related to feature request.

Comments

@tyn1998
Copy link
Member

tyn1998 commented Aug 26, 2023

Description

Users want to share Contributors Activity Racing Bar in the form of video. It is a good idea and also a chance to spread Hypercrx, OpenDigger and X-lab. We should support this feature :)

Watermark: "Powered by OpenDigger and Hypercrx" or "Powered by X-lab"

@tyn1998 tyn1998 added the kind/feature Category issues or prs related to feature request. label Aug 26, 2023
@andyhuang18
Copy link
Collaborator

I think this is a great idea! ! Because Racing Bar is also a very interesting feature. Hi~ @lhbvvvvv , can you give it a try?

@l1tok
Copy link
Collaborator

l1tok commented Aug 30, 2023

I think this is a great idea! ! Because Racing Bar is also a very interesting feature. Hi~ @lhbvvvvv , can you give it a try?

Ok, I can try it.

@tyn1998
Copy link
Member Author

tyn1998 commented Sep 17, 2023

Hi @lhbvvvvv, Do you have any ideas to share with us regarding the implementation of this feature?

@l1tok
Copy link
Collaborator

l1tok commented Sep 18, 2023

I thought about using RecordRTC.js to do this, I did a simple test in my own html file, and now I'm wondering if I can use this in hypercrx.

@tyn1998
Copy link
Member Author

tyn1998 commented Sep 19, 2023

now I'm wondering if I can use this in hypercrx.

If the library can help you to implement the feature, then there you go! A draft PR is also welcomed.


Hi @lhbvvvvv, I have also some information generated by GPT for you. Hope it helps :)

Me:I use ECharts to implement a racing bar chart, now I want to export the animation as a video and I hope the export process entirely happens in the browser, How can I achieve this?
ChatGPT3.5:To export the animation of a racing bar chart created using ECharts as a video entirely within the browser, you can follow these steps:

  1. Create the racing bar chart using ECharts and configure the animation as desired.

  2. Use the ECharts on method to listen for the finished event of the animation. This event is triggered when the animation is complete.

myChart.on('finished', function() {
  // Export the chart animation as a video
});
  1. Inside the event handler function, you can utilize the canvas element and the captureStream() method to capture the chart animation frames.
const canvas = document.querySelector('canvas');
const stream = canvas.captureStream();
  1. Use the MediaRecorder API to record the captured frames and export them as a video file.
const chunks = [];

const mediaRecorder = new MediaRecorder(stream, {
  mimeType: 'video/webm; codecs=vp9'
});

mediaRecorder.ondataavailable = function(event) {
  chunks.push(event.data);
};

mediaRecorder.onstop = function() {
  const blob = new Blob(chunks, { type: 'video/webm' });
  const url = URL.createObjectURL(blob);

  // Create a video element and set the source to the recorded video
  const video = document.createElement('video');
  video.src = url;

  // Download the video
  const a = document.createElement('a');
  a.download = 'chart_animation.webm';
  a.href = url;
  a.click();

  // Clean up
  URL.revokeObjectURL(url);
};

mediaRecorder.start();
  1. Start the media recorder when the animation finishes.
myChart.on('finished', function() {
  mediaRecorder.start();
});

// Stop the media recorder after desired duration
setTimeout(function() {
  mediaRecorder.stop();
}, 5000); // Set the duration as desired or based on the chart animation time

With these steps, the racing bar chart animation will be captured and exported as a video file within the browser.

Me:Why start the record process after the animation finished? I do want to record the animation!
ChatGPT3.5:Apologies for the misunderstanding. If you want to start recording the animation immediately without waiting for it to finish, you can skip the 'finished' event listener and start the media recorder as soon as the chart is rendered. Here's an updated code example:

// Create the racing bar chart using ECharts and configure the animation as desired
const myChart = echarts.init(document.getElementById('chart'));

// ...

// Capture the canvas element
const canvas = document.querySelector('canvas');
const stream = canvas.captureStream();

// Start the media recorder
const chunks = [];
const mediaRecorder = new MediaRecorder(stream, {
  mimeType: 'video/webm; codecs=vp9'
});

mediaRecorder.ondataavailable = function(event) {
  chunks.push(event.data);
};

// Start recording immediately
mediaRecorder.start();

// Stop the media recorder after desired duration or when the animation is complete
setTimeout(function() {
  mediaRecorder.stop();
}, 5000); // Set the duration as desired or based on the chart animation time

// Handle the stop event
mediaRecorder.onstop = function() {
  const blob = new Blob(chunks, { type: 'video/webm' });
  const url = URL.createObjectURL(blob);

  // Create a video element and set the source to the recorded video
  const video = document.createElement('video');
  video.src = url;

  // Download the video
  const a = document.createElement('a');
  a.download = 'chart_animation.webm';
  a.href = url;
  a.click();

  // Clean up
  URL.revokeObjectURL(url);
};

With this modification, the recording process will start immediately upon rendering the chart, capturing the animation frames until the desired duration or when manually stopped.

Me:I want to start the recording process after clicking a start button and finish the record process after the echarts animation finished.
ChatGPT3.5:Understood. To achieve this, you can implement the following steps:

  1. Add a start button to your HTML markup.
<button id="startButton">Start Recording</button>
  1. Modify the JavaScript code to start the recording process when the start button is clicked.
const startButton = document.getElementById('startButton');

// Create a flag to track if recording has started
let recordingStarted = false;

// Event listener for the start button
startButton.addEventListener('click', function() {
  // Start the recording only if it has not already started
  if (!recordingStarted) {
    recordingStarted = true;

    // Capture the canvas element
    const canvas = document.querySelector('canvas');
    const stream = canvas.captureStream();

    // Start the media recorder
    const chunks = [];
    const mediaRecorder = new MediaRecorder(stream, {
      mimeType: 'video/webm; codecs=vp9'
    });

    mediaRecorder.ondataavailable = function(event) {
      chunks.push(event.data);
    };

    // Start recording
    mediaRecorder.start();

    // Stop the media recorder after the animation finishes
    myChart.on('finished', function() {
      if (recordingStarted) {
        recordingStarted = false;
        mediaRecorder.stop();
      }
    });

    // Handle the stop event
    mediaRecorder.onstop = function() {
      const blob = new Blob(chunks, { type: 'video/webm' });
      const url = URL.createObjectURL(blob);

      // Create a video element and set the source to the recorded video
      const video = document.createElement('video');
      video.src = url;

      // Download the video
      const a = document.createElement('a');
      a.download = 'chart_animation.webm';
      a.href = url;
      a.click();

      // Clean up
      URL.revokeObjectURL(url);
    };
  }
});

With this code, the recording process will start only when the start button is clicked. The recording will continue until the ECharts animation finishes or until the stop button is clicked.

Me:The demo code looks good, please also give the explanation of the API used in the code
ChatGPT3.5:Certainly! Here's an explanation of the APIs used in the code:

  1. querySelector: This method is used to select the first element that matches a specified CSS selector. In the code, it is used to select the <canvas> element on which the ECharts chart is rendered.

  2. captureStream(): This method is used to capture the contents of a DOM element, such as a <canvas>, as a media stream. In the code, it is used to capture the frames of the chart animation as a stream.

  3. MediaRecorder: This API allows you to record media streams, such as the one captured from the <canvas> element. It provides methods and events to control and handle the recording process. In the code, it is used to record the captured stream as a video.

    • new MediaRecorder(stream, options): This creates a new MediaRecorder instance, where stream is the media stream to record and options specify the desired configuration, such as the MIME type and codecs for the recorded video.

    • MediaRecorder.ondataavailable: This event is triggered whenever new recorded media becomes available. In the code, it is used to handle the availability of recorded video chunks and store them in an array.

    • MediaRecorder.onstop: This event is triggered when the recording is stopped. In the code, it is used to handle the stop event and perform further actions, such as creating a video element, downloading the recorded video, and cleaning up.

    • MediaRecorder.start(): This method starts the recording process.

    • MediaRecorder.stop(): This method stops the recording process.

  4. URL.createObjectURL(): This method creates a DOMString representing a URL object from a Blob or File object. In the code, it is used to generate a URL for the recorded video blob, allowing it to be set as the source of a video element or used for downloading.

  5. addEventListener(): This method is used to register an event listener on a DOM element. In the code, it is used to listen for the click event on the start button.

I hope this explanation clarifies the usage of the APIs in the code. Let me know if you have any further questions!

@l1tok
Copy link
Collaborator

l1tok commented Sep 19, 2023

Thanks @tyn1998 for your help, it was very useful for me. I have a question how to get the 'finished' status of the chart. I also asked the gpt but didn't get a useful answer.

    // Stop the media recorder after the animation finishes
    myChart.on('finished', function() {
      if (recordingStarted) {
        recordingStarted = false;
        mediaRecorder.stop();
      }
    });

@tyn1998
Copy link
Member Author

tyn1998 commented Sep 19, 2023

@lhbvvvvv you may refer to the docs of ECharts API: https://echarts.apache.org/zh/api.html#events.finished

I guess the event will be fired after each animation triggered by each setOption. So only the last finished event should be used to stop recording.

@l1tok
Copy link
Collaborator

l1tok commented Sep 20, 2023

I encountered this problem when the video recording was finished.
image

@tyn1998
Copy link
Member Author

tyn1998 commented Sep 20, 2023

Seems like a trouble, could you create a draft PR for further discussion on implementation?

@l1tok
Copy link
Collaborator

l1tok commented Sep 20, 2023

I encountered some network problems and couldn't push the code. Then I will tweak the code and submit the pr draft.

@tyn1998
Copy link
Member Author

tyn1998 commented Sep 20, 2023

@lhbvvvvv If you are using Mac, this might help:

image

@l1tok l1tok linked a pull request Sep 22, 2023 that will close this issue
10 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/feature Category issues or prs related to feature request.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants