Skip to main content
Glama
StrudelController.tsโ€ข2.53 kB
import { chromium, Browser, Page } from 'playwright'; import { AudioAnalyzer } from './AudioAnalyzer.js'; export class StrudelController { private browser: Browser | null = null; private page: Page | null = null; private analyzer: AudioAnalyzer; private isHeadless: boolean; constructor(headless: boolean = false) { this.isHeadless = headless; this.analyzer = new AudioAnalyzer(); } async initialize(): Promise<string> { if (this.browser) { return 'Already initialized'; } this.browser = await chromium.launch({ headless: this.isHeadless, args: ['--use-fake-ui-for-media-stream'], }); const context = await this.browser.newContext({ permissions: ['microphone'], }); this.page = await context.newPage(); await this.page.goto('https://strudel.cc/', { waitUntil: 'networkidle', }); await this.page.waitForSelector('.cm-content', { timeout: 10000 }); await this.analyzer.inject(this.page); return 'Strudel initialized successfully'; } async writePattern(pattern: string): Promise<string> { if (!this.page) throw new Error('Not initialized'); await this.page.click('.cm-content'); await this.page.keyboard.press('ControlOrMeta+A'); await this.page.keyboard.type(pattern); return `Pattern written (${pattern.length} chars)`; } async getCurrentPattern(): Promise<string> { if (!this.page) throw new Error('Not initialized'); return await this.page.evaluate(() => { const editor = document.querySelector('.cm-content'); return editor?.textContent || ''; }); } async play(): Promise<string> { if (!this.page) throw new Error('Not initialized'); try { await this.page.click('button[title*="play" i]', { timeout: 1000 }); } catch { await this.page.keyboard.press('ControlOrMeta+Enter'); } await this.page.waitForTimeout(500); return 'Playing'; } async stop(): Promise<string> { if (!this.page) throw new Error('Not initialized'); try { await this.page.click('button[title*="stop" i]', { timeout: 1000 }); } catch { await this.page.keyboard.press('ControlOrMeta+Period'); } return 'Stopped'; } async analyzeAudio(): Promise<any> { if (!this.page) throw new Error('Not initialized'); return await this.analyzer.getAnalysis(this.page); } async cleanup() { if (this.browser) { await this.browser.close(); this.browser = null; this.page = null; } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/williamzujkowski/strudel-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server