{"id":28619282,"url":"https://github.com/mlshukai/pamiq-recorder","last_synced_at":"2026-03-16T08:33:04.837Z","repository":{"id":287168624,"uuid":"963831861","full_name":"MLShukai/pamiq-recorder","owner":"MLShukai","description":"Simple, modern, and type-safe recording library for P-AMI\u003cQ\u003e","archived":false,"fork":false,"pushed_at":"2025-06-12T02:11:57.000Z","size":177,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-12T03:28:43.857Z","etag":null,"topics":["audio","csv","python3","recorder","video"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MLShukai.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-10T09:22:00.000Z","updated_at":"2025-06-12T02:11:58.000Z","dependencies_parsed_at":null,"dependency_job_id":"2998d473-a01a-4d7e-a365-cedc03ba49f5","html_url":"https://github.com/MLShukai/pamiq-recorder","commit_stats":null,"previous_names":["mlshukai/pamiq-recorder"],"tags_count":3,"template":false,"template_full_name":"Geson-anko/python-uv-template","purl":"pkg:github/MLShukai/pamiq-recorder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MLShukai%2Fpamiq-recorder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MLShukai%2Fpamiq-recorder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MLShukai%2Fpamiq-recorder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MLShukai%2Fpamiq-recorder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MLShukai","download_url":"https://codeload.github.com/MLShukai/pamiq-recorder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MLShukai%2Fpamiq-recorder/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259397235,"owners_count":22851191,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["audio","csv","python3","recorder","video"],"created_at":"2025-06-12T04:30:35.419Z","updated_at":"2026-03-16T08:32:59.812Z","avatar_url":"https://github.com/MLShukai.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"![logo](./docs/images/logo.svg)\n\n# pamiq-recorder\n\n[![Formatter \u0026 Linter / Tests / Type Check](https://github.com/MLShukai/pamiq-recorder/actions/workflows/main.yml/badge.svg)](https://github.com/MLShukai/pamiq-recorder/actions/workflows/main.yml)\n[![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Document Style](https://img.shields.io/badge/%20docstyle-google-3666d6.svg)](https://google.github.io/styleguide/pyguide.html#s3.8-comments-and-docstrings)\n\n**pamiq-recorder** is a simple, modern, and type-safe recording library for P-AMI\\\u003cQ\u003e, providing easy and consistent interfaces for video, audio, and CSV data recording.\n\n## ✨ Features\n\n- 📹 Video recording via OpenCV with support for multiple formats\n- 🎵 Audio recording via SoundFile with various audio formats\n- 📊 CSV recording with automatic timestamping\n- 📦 JSONL (JSON Lines): Line-delimited JSON format for streaming data records\n- 🔗 Seamless integration with [**PAMIQ-Core**](https://github.com/MLShukai/pamiq-core) framework using `to_wrapper` factory method.\n- 🔍 Type-safe interfaces with complete type annotations\n- 🧪 Comprehensive test coverage\n\n## 📦 Installation\n\n```bash\n# Install with pip\npip install pamiq-recorder\n\n# For development setup\ngit clone https://github.com/MLShukai/pamiq-recorder.git\ncd pamiq-recorder\nmake venv  # Sets up virtual environment with all dependencies\n```\n\n## 🧰 Requirements\n\n- Python 3.12+\n- OpenCV (for video recording, `libopencv-dev` for Ubuntu.)\n- SoundFile (for audio recording, `libsndfile1` for Ubuntu.)\n\n## 📝 Usage\n\n### PAMIQ-Core Integration\n\nAll recorders provide seamless integration with the PAMIQ-Core framework through wrapper functionality, allowing you to easily record data from sensors and observations:\n\n```python\nfrom pamiq_recorder import VideoRecorder\nfrom pamiq_core.interaction.wrappers import SensorWrapper\n\n# Create a camera sensor\ncamera_sensor = YourCameraSensor()  # Your implementation of a sensor class\n\n# Wrap the camera sensor to record all observations\nwrapped_sensor = SensorWrapper(\n    camera_sensor,\n    VideoRecorder.to_wrapper(\n        save_dir=\"./camera_recordings\",\n        fps=30.0,\n        height=480,\n        width=640,\n        channels=3\n    )\n)\n```\n\nRecording wrappers automatically:\n\n- Create new recordings with timestamped filenames\n- Close recordings when the system pauses\n- Create fresh recordings when the system resumes\n- Clean up resources properly during teardown\n\n### Video Recording\n\n```python\nfrom pamiq_recorder import VideoRecorder\nimport numpy as np\n\n# Create a video recorder for RGB video\nrecorder = VideoRecorder(\n    file_path=\"output.mp4\",\n    fps=30.0,\n    height=480,\n    width=640,\n    channels=3  # RGB format\n)\n\n# Create a sample frame (RGB gradient)\nframe = np.zeros((480, 640, 3), dtype=np.uint8)\nfor i in range(480):\n    for j in range(640):\n        frame[i, j, 0] = i * 255 // 480  # Red gradient\n        frame[i, j, 1] = j * 255 // 640  # Green gradient\n        frame[i, j, 2] = (i + j) * 255 // 1120  # Blue gradient\n\n# Write the frame to the video\nrecorder.write(frame)\n\n# Close when done\nrecorder.close()\n```\n\n### Audio Recording\n\n```python\nfrom pamiq_recorder import AudioRecorder\nimport numpy as np\n\n# Create an audio recorder for stereo audio\nrecorder = AudioRecorder(\n    file_path=\"output.wav\",\n    sample_rate=44100,\n    channels=2\n)\n\n# Create a simple stereo sine wave\nduration = 5.0  # seconds\nt = np.linspace(0, duration, int(duration * 44100), endpoint=False)\n\n# Left channel: 440 Hz, Right channel: 880 Hz\nleft = np.sin(2 * np.pi * 440 * t)\nright = np.sin(2 * np.pi * 880 * t)\n\n# Combine into stereo data with shape (samples, channels)\ndata = np.column_stack((left, right)).astype(np.float32)\n\n# Write the audio data\nrecorder.write(data)\n\n# Close when done\nrecorder.close()\n```\n\n### CSV Recording\n\n```python\nfrom pamiq_recorder import CsvRecorder\nimport time\n\n# Create a CSV recorder with custom headers\nrecorder = CsvRecorder(\n    file_path=\"sensor_data.csv\",\n    headers=[\"temperature\", \"humidity\", \"pressure\"],\n    timestamp_header=\"time\"\n)\n\n# Write some sample data rows\nrecorder.write([25.4, 60.2, 1013.25])\ntime.sleep(1)\nrecorder.write([25.5, 60.0, 1013.20])\ntime.sleep(1)\nrecorder.write([25.6, 59.8, 1013.15])\n\n# Close when done\nrecorder.close()\n```\n\n### JSONL Recording\n\n```python\nfrom pamiq_recorder import JsonlRecorder\nimport time\n\n# Create a JSONL recorder\nrecorder = JsonlRecorder(\n    file_path=\"sensor_data.jsonl\",\n    ensure_ascii=False  # Optional: Allow direct Unicode characters\n)\n\n# Write various data types\nrecorder.write(\"Simple string\")\nrecorder.write(42)\nrecorder.write({\"temperature\": 25.4, \"humidity\": 60.2, \"pressure\": 1013.25})\n\n# Complex nested structures\nrecorder.write({\n    \"device_info\": {\n        \"id\": \"sensor-12345\",\n        \"location\": \"room-1\",\n        \"firmware\": \"v2.1.3\"\n    },\n    \"readings\": [\n        {\"type\": \"temperature\", \"value\": 25.4},\n        {\"type\": \"humidity\", \"value\": 60.2}\n    ],\n    \"status\": \"active\"\n})\n\n# Close when done\nrecorder.close()\n```\n\nThe JsonlRecorder stores data in the JSON Lines format (also known as JSONL or Line-delimited JSON), where each line is a valid, independent JSON object.\n\nEach line is saved in the format `{\"timestamp\": 1619855734.123, \"data\": ...}` where the timestamp is automatically added and the data can be any JSON-serializable value.\n\n### Using Context Managers\n\nAll recorders support the context manager protocol for automatic resource cleanup:\n\n```python\nimport numpy as np\nfrom pamiq_recorder import AudioRecorder\n\n# Audio data to write\ndata = np.random.rand(44100, 2).astype(np.float32)  # 1 second of random stereo audio\n\n# Use with statement for automatic closing\nwith AudioRecorder(\"output.wav\", sample_rate=44100, channels=2) as recorder:\n    recorder.write(data)\n    # No need to call close() - it happens automatically\n```\n\n## 🔧 Supported Formats\n\n### Video Formats\n\n- MP4 (mp4v codec)\n- AVI (XVID codec)\n- MOV (mp4v codec)\n- MKV (X264 codec)\n\n### Audio Formats\n\n- WAV\n- FLAC\n- OGG/Vorbis\n- OGG/Opus\n- MP3\n- M4A/ALAC\n- MOV/ALAC\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n1. Fork the repository\n2. Create your feature branch (`git checkout -b feature/amazing-feature`)\n3. Run all workflow (`make run`)\n4. Commit your changes (`git commit -m 'Add some amazing feature'`)\n5. Push to the branch (`git push origin feature/amazing-feature`)\n6. Open a Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlshukai%2Fpamiq-recorder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmlshukai%2Fpamiq-recorder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmlshukai%2Fpamiq-recorder/lists"}