LoginSignup
1
0

Teams会議で発言時間を集計する (VTT対応版)

Last updated at Posted at 2023-06-22

会議の PDCA

「相手の話を聞けていたかな?」
「ファシリテーション、うまく回っていたかな?」
「与えられた時間内で発表できたかな?」

確認してみよう (Check)

お試しは こちら からどうぞ

手順

  1. コード をテキストエディタなどにコピペしてHTMLファイル形式で保存する
    image.png

  2. 会議で 文字起こしを開始 する
    image.png

  3. 会議が終われば、文字起こしを .vttとしてダウンロード する
    image.png

  4. 1 で保存したHTMLをブラウザで開く
    image.png

  5. ファイルを選択 を押して、3 で保存したVTTファイルを指定する
    image.png

以上

コード

<!DOCTYPE html>
<html>
<head>
  <title>Teams会議 発話時間統計</title>
<style>
th, td {
  border: 1px solid gray;
  padding: 4px;
}
table {
  border-collapse: collapse;
}
</style>
</head>
<body>
  <input type="file" accept=".txt,.vtt" id="fileInput">
  <p><b>ファイル統計</b></p>
  <div id="statistics"></div>
  <p><b>発話時間統計</b></p>
  <div id="speaking"></div>

<script>
document.getElementById('fileInput').addEventListener('change', handleFileUpload);

function handleFileUpload(event) {
  const file = event.target.files[0];

  const reader = new FileReader();
  reader.onload = function(event) {
    const fileContent = event.target.result;
    parseAndDisplayStatistics(fileContent);
  };
  reader.readAsText(file);
}

function parseAndDisplayStatistics(fileContent) {
  const lines = fileContent.split('\n');
  const lineCount = lines.length;
  const wordCount = countWords(lines);

  const statisticsDiv = document.getElementById('statistics');
  statisticsDiv.innerHTML = `行数: ${lineCount}<br>単語数: ${wordCount}`;

  const hash = lines[0].startsWith("WEBVTT") ? countSpeakingTimeVtt(lines) : countSpeakingTimeTxt(lines);
  const sorted = Object.fromEntries(Object.entries(hash).sort((a, b) => b[1] - a[1]));
  console.log(hash);
  console.log(sorted);

  var html = '<table><tr><th>発話者<th>発話時間<th>ms</tr>';
  for (let key in sorted) {
    if (hash.hasOwnProperty(key)) {
      const value = hash[key];
      // ハッシュの各要素に対して行いたい処理をここに記述
      const hours   = Math.floor( value / (1000 * 60 * 60));
      const minutes = Math.floor((value % (1000 * 60 * 60)) / (1000 * 60));
      const seconds = Math.floor((value % (1000 * 60)) / 1000);
      const remainingMilliseconds = value % 1000;
      html += `<tr><td>${key}<td>${hours}時間 ${minutes}${seconds}秒<td align=right>${value} ms</tr>`;
      console.log(`Key: ${key}, Value: ${value}`);
    }
  }
  document.getElementById('speaking').innerHTML = html + '</table>';
}

function countWords(lines) {
  let wordCount = 0;
  for (let i = 0; i < lines.length; i++) {
    const words = lines[i].trim().split(/\s+/);
    wordCount += words.length;
  }
  return wordCount;
}

// 発話時間を話者ごとに集計する (.txt)
// 入力フォーマット:
//   0:0:1.130 --> 0:0:2.700
//   発話者の名前
//   あお疲れ様です。
function countSpeakingTimeTxt(lines) {
  var speakingTime = {}; // empty hash
  for (let i = 0; i + 2 < lines.length; i += 3) {
    console.log('line : ' + i);
    // 1st line (time)
    const resultArray = parseTimeLine(lines[i]);
    console.log("begin : " + resultArray[0]);
    console.log("end   : " + resultArray[1]);

    const time_begin = parseTimeString(resultArray[0]);
    const time_end   = parseTimeString(resultArray[1]);
    const elapsed_ms = getElapsedMilliSeconds(time_begin, time_end);
    console.log(elapsed_ms + "ms");
    
    // 2nd line (speaker name)
    console.log("speaker : " + lines[i + 1]);
    const total  = speakingTime[lines[i + 1]];
    const update = total ? total + elapsed_ms : elapsed_ms;
    speakingTime[lines[i + 1]] = update;

    // 3rd line (speaking contents - ignore)
  }
  return speakingTime;
}

// 発話時間を話者ごとに集計する (.vtt)
// 入力フォーマット:
//   WEBVTT
//   { 空行 }
//   00:00:00.000 --> 00:00:00.560
//   <v 発話者の名前>ええ</v>
//   { 空行 }
function countSpeakingTimeVtt(lines) {
  var speakingTime = {}; // empty hash
  for (let i = 2; i + 1 < lines.length; i += 3) {
    console.log('line : ' + i);
    // 1st line (time)
    const resultArray = parseTimeLine(lines[i]);
    console.log("begin : " + resultArray[0]);
    console.log("end   : " + resultArray[1]);

    const time_begin = parseTimeString(resultArray[0]);
    const time_end   = parseTimeString(resultArray[1]);
    const elapsed_ms = getElapsedMilliSeconds(time_begin, time_end);
    console.log(elapsed_ms + "ms");
    
    // 2nd line (speaker name + contents)
    const [str1, str2] = lines[i + 1].split('>');
    const speaker = str1.substring(3);
    console.log("speaker : " + speaker);
    const total  = speakingTime[speaker];
    const update = total ? total + elapsed_ms : elapsed_ms;
    speakingTime[speaker] = update;

    // 3rd line (empty line - ignore)
  }
  return speakingTime;
}

function parseTimeLine(timeLineString) {
  const [t1, allow, t2] = timeLineString.split(' ');
  return [t1, t2];
}

function parseTimeString(timeString) {
  const [hour, minute, second, millisecond] = timeString.split(/[:.]/);
  const currentDate = new Date();
  currentDate.setHours(hour);
  currentDate.setMinutes(minute);
  currentDate.setSeconds(second);
  currentDate.setMilliseconds(millisecond);
  return currentDate;
}

function getElapsedMilliSeconds(date1, date2) {
  return Math.abs(date2 - date1);
}
</script>
</body>
</html>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0