Agent Skills by ALSEL
Anthropic Claude音声・動画・メディア⭐ リポ 1品質スコア 58/100

deepgram-performance-tuning

Deepgram APIのパフォーマンスを最適化し、文字起こしの高速化とレイテンシー低減を実現します。文字起こしの速度向上、レイテンシーの削減、音声処理パイプラインの最適化が必要な場合に活用できます。「deepgram performance」「speed up deepgram」「optimize transcription」「deepgram latency」「deepgram faster」といったフレーズでトリガーされます。

description の原文を見る

Optimize Deepgram API performance for faster transcription and lower latency. Use when improving transcription speed, reducing latency, or optimizing audio processing pipelines. Trigger with phrases like "deepgram performance", "speed up deepgram", "optimize transcription", "deepgram latency", "deepgram faster".

SKILL.md 本文

Deepgram パフォーマンス チューニング

概要

オーディオの前処理、接続管理、設定チューニングを通じて Deepgram 統合のパフォーマンスを最適化します。

前提条件

  • 動作する Deepgram 統合
  • パフォーマンス監視の実施
  • オーディオ処理機能
  • ベースラインメトリクスの確立

パフォーマンス要因

要因影響最適化
オーディオ形式最適なエンコーディングを使用
サンプリングレートモデル要件に合わせる
ファイルサイズ大きなファイルはストリーミング
モデル選択精度と速度のバランスを調整
ネットワークレイテンシ最も近いリージョンを使用
同時実行数接続を管理

手順

ステップ 1: オーディオ形式を最適化

最適な文字起こしのためにオーディオを前処理します。

ステップ 2: 接続プーリングを設定

接続を再利用してスループットを向上させます。

ステップ 3: API パラメータをチューニング

適切なモデルと機能を選択します。

ステップ 4: ストリーミングを実装

リアルタイムと大きなファイル用にストリーミングを使用します。

オーディオ前処理

// lib/audio-optimizer.ts
import ffmpeg from 'fluent-ffmpeg';
import { Readable } from 'stream';

interface OptimizedAudio {
  buffer: Buffer;
  mimetype: string;
  sampleRate: number;
  channels: number;
  duration: number;
}

export async function optimizeAudio(inputPath: string): Promise<OptimizedAudio> {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];

    // Optimal settings for Deepgram
    ffmpeg(inputPath)
      .audioCodec('pcm_s16le')      // 16-bit PCM
      .audioChannels(1)              // Mono
      .audioFrequency(16000)         // 16kHz (optimal for speech)
      .format('wav')
      .on('error', reject)
      .on('end', () => {
        const buffer = Buffer.concat(chunks);
        resolve({
          buffer,
          mimetype: 'audio/wav',
          sampleRate: 16000,
          channels: 1,
          duration: buffer.length / (16000 * 2), // 16-bit = 2 bytes
        });
      })
      .pipe()
      .on('data', (chunk: Buffer) => chunks.push(chunk));
  });
}

// For already loaded audio data
export async function optimizeAudioBuffer(
  audioBuffer: Buffer,
  inputFormat: string
): Promise<Buffer> {
  return new Promise((resolve, reject) => {
    const chunks: Buffer[] = [];
    const readable = new Readable();
    readable.push(audioBuffer);
    readable.push(null);

    ffmpeg(readable)
      .inputFormat(inputFormat)
      .audioCodec('pcm_s16le')
      .audioChannels(1)
      .audioFrequency(16000)
      .format('wav')
      .on('error', reject)
      .on('end', () => resolve(Buffer.concat(chunks)))
      .pipe()
      .on('data', (chunk: Buffer) => chunks.push(chunk));
  });
}

接続プーリング

// lib/connection-pool.ts
import { createClient, DeepgramClient } from '@deepgram/sdk';

interface PoolConfig {
  minSize: number;
  maxSize: number;
  acquireTimeout: number;
  idleTimeout: number;
}

class DeepgramConnectionPool {
  private pool: DeepgramClient[] = [];
  private inUse: Set<DeepgramClient> = new Set();
  private waiting: Array<(client: DeepgramClient) => void> = [];
  private config: PoolConfig;
  private apiKey: string;

  constructor(apiKey: string, config: Partial<PoolConfig> = {}) {
    this.apiKey = apiKey;
    this.config = {
      minSize: config.minSize ?? 2,
      maxSize: config.maxSize ?? 10,
      acquireTimeout: config.acquireTimeout ?? 10000,
      idleTimeout: config.idleTimeout ?? 60000,
    };

    // Initialize minimum connections
    for (let i = 0; i < this.config.minSize; i++) {
      this.pool.push(createClient(this.apiKey));
    }
  }

  async acquire(): Promise<DeepgramClient> {
    // Try to get from pool
    if (this.pool.length > 0) {
      const client = this.pool.pop()!;
      this.inUse.add(client);
      return client;
    }

    // Create new if under max
    if (this.inUse.size < this.config.maxSize) {
      const client = createClient(this.apiKey);
      this.inUse.add(client);
      return client;
    }

    // Wait for available connection
    return new Promise((resolve, reject) => {
      const timeout = setTimeout(() => {
        const index = this.waiting.indexOf(resolve);
        if (index > -1) this.waiting.splice(index, 1);
        reject(new Error('Connection acquire timeout'));
      }, this.config.acquireTimeout);

      this.waiting.push((client) => {
        clearTimeout(timeout);
        resolve(client);
      });
    });
  }

  release(client: DeepgramClient): void {
    this.inUse.delete(client);

    if (this.waiting.length > 0) {
      const waiter = this.waiting.shift()!;
      this.inUse.add(client);
      waiter(client);
    } else {
      this.pool.push(client);
    }
  }

  async execute<T>(fn: (client: DeepgramClient) => Promise<T>): Promise<T> {
    const client = await this.acquire();
    try {
      return await fn(client);
    } finally {
      this.release(client);
    }
  }

  getStats() {
    return {
      poolSize: this.pool.length,
      inUse: this.inUse.size,
      waiting: this.waiting.length,
    };
  }
}

export const pool = new DeepgramConnectionPool(process.env.DEEPGRAM_API_KEY!);

大きなファイル用ストリーミング

// lib/streaming-transcription.ts
import { createClient } from '@deepgram/sdk';
import { createReadStream, statSync } from 'fs';

interface StreamingOptions {
  chunkSize: number;
  model: string;
}

export async function streamLargeFile(
  filePath: string,
  options: Partial<StreamingOptions> = {}
): Promise<string> {
  const { chunkSize = 1024 * 1024, model = 'nova-2' } = options;
  const client = createClient(process.env.DEEPGRAM_API_KEY!);

  const fileSize = statSync(filePath).size;
  const transcripts: string[] = [];

  // Use live transcription for streaming
  const connection = client.listen.live({
    model,
    smart_format: true,
    punctuate: true,
  });

  return new Promise((resolve, reject) => {
    connection.on('open', () => {
      const stream = createReadStream(filePath, { highWaterMark: chunkSize });

      stream.on('data', (chunk: Buffer) => {
        connection.send(chunk);
      });

      stream.on('end', () => {
        connection.finish();
      });

      stream.on('error', reject);
    });

    connection.on('transcript', (data) => {
      if (data.is_final) {
        transcripts.push(data.channel.alternatives[0].transcript);
      }
    });

    connection.on('close', () => {
      resolve(transcripts.join(' '));
    });

    connection.on('error', reject);
  });
}

速度のためのモデル選択

// lib/model-selector.ts
interface ModelConfig {
  name: string;
  accuracy: 'high' | 'medium' | 'low';
  speed: 'fast' | 'medium' | 'slow';
  costPerMinute: number;
}

const models: Record<string, ModelConfig> = {
  'nova-2': {
    name: 'Nova-2',
    accuracy: 'high',
    speed: 'fast',
    costPerMinute: 0.0043,
  },
  'nova': {
    name: 'Nova',
    accuracy: 'high',
    speed: 'fast',
    costPerMinute: 0.0043,
  },
  'enhanced': {
    name: 'Enhanced',
    accuracy: 'medium',
    speed: 'fast',
    costPerMinute: 0.0145,
  },
  'base': {
    name: 'Base',
    accuracy: 'low',
    speed: 'fast',
    costPerMinute: 0.0048,
  },
};

export function selectModel(requirements: {
  prioritize: 'accuracy' | 'speed' | 'cost';
  minAccuracy?: 'high' | 'medium' | 'low';
}): string {
  const { prioritize, minAccuracy = 'low' } = requirements;

  const accuracyOrder = ['high', 'medium', 'low'];
  const minAccuracyIndex = accuracyOrder.indexOf(minAccuracy);

  const eligible = Object.entries(models).filter(([_, config]) =>
    accuracyOrder.indexOf(config.accuracy) <= minAccuracyIndex
  );

  if (prioritize === 'accuracy') {
    return eligible.reduce((best, [name, config]) =>
      accuracyOrder.indexOf(config.accuracy) < accuracyOrder.indexOf(models[best].accuracy)
        ? name : best
    , eligible[0][0]);
  }

  if (prioritize === 'cost') {
    return eligible.reduce((best, [name, config]) =>
      config.costPerMinute < models[best].costPerMinute ? name : best
    , eligible[0][0]);
  }

  // Default: balance speed and accuracy
  return 'nova-2';
}

並列処理

// lib/parallel-transcription.ts
import { pool } from './connection-pool';
import pLimit from 'p-limit';

interface TranscriptionResult {
  file: string;
  transcript: string;
  duration: number;
}

export async function transcribeMultiple(
  audioUrls: string[],
  concurrency = 5
): Promise<TranscriptionResult[]> {
  const limit = pLimit(concurrency);
  const startTime = Date.now();

  const results = await Promise.all(
    audioUrls.map((url, index) =>
      limit(async () => {
        const itemStart = Date.now();

        const result = await pool.execute(async (client) => {
          const { result, error } = await client.listen.prerecorded.transcribeUrl(
            { url },
            { model: 'nova-2', smart_format: true }
          );

          if (error) throw error;
          return result;
        });

        return {
          file: url,
          transcript: result.results.channels[0].alternatives[0].transcript,
          duration: Date.now() - itemStart,
        };
      })
    )
  );

  console.log(`Processed ${audioUrls.length} files in ${Date.now() - startTime}ms`);
  console.log(`Average per file: ${(Date.now() - startTime) / audioUrls.length}ms`);

  return results;
}

結果のキャッシング

// lib/transcription-cache.ts
import { createHash } from 'crypto';
import { redis } from './redis';

interface CacheOptions {
  ttl: number; // seconds
}

export class TranscriptionCache {
  private ttl: number;

  constructor(options: Partial<CacheOptions> = {}) {
    this.ttl = options.ttl ?? 3600; // 1 hour default
  }

  private getCacheKey(audioUrl: string, options: Record<string, unknown>): string {
    const hash = createHash('sha256')
      .update(JSON.stringify({ audioUrl, options }))
      .digest('hex');
    return `transcription:${hash}`;
  }

  async get(
    audioUrl: string,
    options: Record<string, unknown>
  ): Promise<string | null> {
    const key = this.getCacheKey(audioUrl, options);
    return redis.get(key);
  }

  async set(
    audioUrl: string,
    options: Record<string, unknown>,
    transcript: string
  ): Promise<void> {
    const key = this.getCacheKey(audioUrl, options);
    await redis.setex(key, this.ttl, transcript);
  }

  async transcribeWithCache(
    transcribeFn: () => Promise<string>,
    audioUrl: string,
    options: Record<string, unknown>
  ): Promise<{ transcript: string; cached: boolean }> {
    const cached = await this.get(audioUrl, options);
    if (cached) {
      return { transcript: cached, cached: true };
    }

    const transcript = await transcribeFn();
    await this.set(audioUrl, options, transcript);

    return { transcript, cached: false };
  }
}

パフォーマンスメトリクス

// lib/performance-metrics.ts
import { Histogram, Counter, Gauge } from 'prom-client';

export const transcriptionLatency = new Histogram({
  name: 'deepgram_transcription_latency_seconds',
  help: 'Latency of transcription requests',
  labelNames: ['model', 'status'],
  buckets: [0.5, 1, 2, 5, 10, 30, 60],
});

export const audioDuration = new Histogram({
  name: 'deepgram_audio_duration_seconds',
  help: 'Duration of audio files processed',
  buckets: [10, 30, 60, 120, 300, 600, 1800],
});

export const processingRatio = new Gauge({
  name: 'deepgram_processing_ratio',
  help: 'Ratio of processing time to audio duration',
  labelNames: ['model'],
});

export function measureTranscription(
  audioDurationSec: number,
  processingTimeSec: number,
  model: string
) {
  audioDuration.observe(audioDurationSec);
  processingRatio.labels(model).set(processingTimeSec / audioDurationSec);
}

リソース

次のステップ

コスト最適化については deepgram-cost-tuning に進みます。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
Brmbobo
リポジトリ
Brmbobo/Web2podcast
ライセンス
MIT
最終更新
2026/1/26

Source: https://github.com/Brmbobo/Web2podcast / ライセンス: MIT

関連スキル

汎用音声・動画・メディア⭐ リポ 1,982

listenhub

あらゆることを説明できます。アイデアをポッドキャスト、解説動画、または音声ナレーションに変換します。 ユーザーが「ポッドキャストを作りたい」「解説動画を作成したい」「これを読み上げてほしい」「画像を生成したい」、または知識を音声・映像形式で共有したいときに使用します。トピックの説明、YouTubeリンク、記事URL、プレーンテキスト、画像プロンプトに対応しています。

by LeoYeAI
汎用音声・動画・メディア⭐ リポ 1,982

best-youtube-video-editor

ClawHub上の「best-youtube-video-editor」スキルは、YouTube クリエイターのコンテンツ制作を革新します。タイムラインや複雑なソフトウェアを必要とせず、会話形式のAI駆動型ビデオ編集が可能です。無音部分のカット、チャプターマーカーの追加、字幕の挿入、ペーシングの調整、エクスポートの最適化——すべてが自然言語の指示で実現します。初回使用時には NemoVideo API を通じて認証情報を自動設定するため、有効化後数秒で編集を開始できます。YouTuber、教育関係者、ポッドキャスター、ブランドチャネル向けに開発され、品質を損なわず高速な納期対応が必要な方に最適です。mp4、mov、avi、webm、mkv 形式に対応しています。

by LeoYeAI
汎用音声・動画・メディア⭐ リポ 27,990

video

ユーザーがAIツールやプログラマティックフレームワークを使用してビデオコンテンツを作成、生成、または制作したい場合に使用します。また、ユーザーが「ビデオ制作」「AIビデオ」「Remotion」「Hyperframes」「HeyGen」「Synthesia」「Veo」「Runway」「Kling」「Pika」「ビデオ生成」「AIアバター」「トーキングヘッドビデオ」「プログラマティックビデオ」「ビデオテンプレート」「解説ビデオ」「プロダクトデモビデオ」「ビデオパイプライン」または「ビデオを作ってほしい」と言及している場合にも使用します。ビデオ作成、生成、制作のワークフロー全般に対応できます。ビデオコンテンツの戦略や投稿内容については「social-content」を、有料ビデオ広告クリエイティブについては「ad-creative」をご参照ください。

by coreyhaines31
汎用音声・動画・メディア⭐ リポ 317

clipify

ビデオから最も面白い瞬間を検出し、スタンドアロンクリップとしてカットできます。オプションで16:9から9:16へのリフォーマット(フェイスパンまたはスプリットスクリーン)に対応し、Opus風の単語ごとのキャプションを焼き込みます。ユーザーが「clipify」「このビデオからクリップをカットして」「これからショーツを作って」「面白い瞬間を見つけて」「9:16にリフレーミングして」「縦型クリップ」と言及したり、ビデオファイルパスを貼り付けてSNS対応のクリップを求める場合に使用します。

by louisedesadeleer
OpenAI音声・動画・メディア⭐ リポ 18,898

speech

ユーザーが音声生成、ナレーション、アクセシビリティ対応の読み上げ、音声プロンプト、またはOpenAI Audio APIによるバッチ音声生成をリクエストした場合に使用します。組み込みボイスを備えたバンドルCLI(`scripts/text_to_speech.py`)を実行でき、ライブ呼び出しには`OPENAI_API_KEY`が必要です。カスタムボイスの作成には対応していません。

by openai
汎用音声・動画・メディア⭐ リポ 2,743

depth-estimation

Depth Anything v2を使用したリアルタイム深度マップのプライバシー変換(CoreML + PyTorch対応) このスキルは、Depth Anything v2モデルを活用して、画像やビデオから取得した深度情報をリアルタイムで処理し、プライバシーを保護しながら変換します。CoreMLとPyTorchの両方に対応しており、エッジデバイスでの高速処理とクラウド環境での柔軟な運用が可能です。顔認識データのぼかしや背景の匿名化など、プライバシー関連の処理を効率的に実行できます。

by SharpAI
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: Brmbobo · Brmbobo/Web2podcast · ライセンス: MIT