You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
211 lines
20 KiB
211 lines
20 KiB
2 years ago
|
/*
|
||
|
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
||
|
if you want to view the source, please visit the github repository of this plugin
|
||
|
*/
|
||
|
|
||
|
var __create = Object.create;
|
||
|
var __defProp = Object.defineProperty;
|
||
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
||
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
||
|
var __getProtoOf = Object.getPrototypeOf;
|
||
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
||
|
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
|
||
|
var __export = (target, all) => {
|
||
|
__markAsModule(target);
|
||
|
for (var name in all)
|
||
|
__defProp(target, name, { get: all[name], enumerable: true });
|
||
|
};
|
||
|
var __reExport = (target, module2, desc) => {
|
||
|
if (module2 && typeof module2 === "object" || typeof module2 === "function") {
|
||
|
for (let key of __getOwnPropNames(module2))
|
||
|
if (!__hasOwnProp.call(target, key) && key !== "default")
|
||
|
__defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
|
||
|
}
|
||
|
return target;
|
||
|
};
|
||
|
var __toModule = (module2) => {
|
||
|
return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
|
||
|
};
|
||
|
var __async = (__this, __arguments, generator) => {
|
||
|
return new Promise((resolve, reject) => {
|
||
|
var fulfilled = (value) => {
|
||
|
try {
|
||
|
step(generator.next(value));
|
||
|
} catch (e) {
|
||
|
reject(e);
|
||
|
}
|
||
|
};
|
||
|
var rejected = (value) => {
|
||
|
try {
|
||
|
step(generator.throw(value));
|
||
|
} catch (e) {
|
||
|
reject(e);
|
||
|
}
|
||
|
};
|
||
|
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
||
|
step((generator = generator.apply(__this, __arguments)).next());
|
||
|
});
|
||
|
};
|
||
|
|
||
|
// main.ts
|
||
|
__export(exports, {
|
||
|
default: () => ObsidianCamera
|
||
|
});
|
||
|
var import_obsidian = __toModule(require("obsidian"));
|
||
|
var ObsidianCamera = class extends import_obsidian.Plugin {
|
||
|
onload() {
|
||
|
return __async(this, null, function* () {
|
||
|
this.addRibbonIcon("camera", "Obsidian Camera", (evt) => {
|
||
|
new CameraModal(this.app).open();
|
||
|
});
|
||
|
this.addCommand({
|
||
|
id: "Open camera modal",
|
||
|
name: "Open camera modal / File Picker",
|
||
|
callback: () => {
|
||
|
new CameraModal(this.app).open();
|
||
|
}
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
};
|
||
|
var CameraModal = class extends import_obsidian.Modal {
|
||
|
constructor(app2) {
|
||
|
super(app2);
|
||
|
}
|
||
|
onOpen() {
|
||
|
return __async(this, null, function* () {
|
||
|
const { contentEl } = this;
|
||
|
const webCamContainer = contentEl.createDiv();
|
||
|
const videoEl = webCamContainer.createEl("video");
|
||
|
videoEl.autoplay = true;
|
||
|
videoEl.muted = true;
|
||
|
const recordVideoButton = webCamContainer.createEl("button", {
|
||
|
text: "Start recording"
|
||
|
});
|
||
|
const switchCameraButton = webCamContainer.createEl("button", {
|
||
|
text: "Switch Camera"
|
||
|
});
|
||
|
const snapPhotoButton = webCamContainer.createEl("button", {
|
||
|
text: "Take a snap"
|
||
|
});
|
||
|
const filePicker = webCamContainer.createEl("input", {
|
||
|
placeholder: "Choose image file from system",
|
||
|
type: "file"
|
||
|
});
|
||
|
filePicker.accept = "image/*,video/*";
|
||
|
filePicker.capture = "camera";
|
||
|
const filePicker2 = webCamContainer.createEl("input", {
|
||
|
placeholder: "Choose image file from system",
|
||
|
type: "file"
|
||
|
});
|
||
|
filePicker2.accept = "image/*";
|
||
|
filePicker2.capture = "camera";
|
||
|
const chosenFolderPath = "attachments/snaps";
|
||
|
const chunks = [];
|
||
|
let recorder = null;
|
||
|
let videoStream = null;
|
||
|
const cameras = (yield navigator.mediaDevices.enumerateDevices()).filter((d) => d.kind === "videoinput");
|
||
|
if (cameras.length <= 1)
|
||
|
switchCameraButton.style.display = "none";
|
||
|
let cameraIndex = 0;
|
||
|
const getVideoStream = () => __async(this, null, function* () {
|
||
|
try {
|
||
|
return yield navigator.mediaDevices.getUserMedia({
|
||
|
video: { deviceId: cameras[cameraIndex].deviceId },
|
||
|
audio: true
|
||
|
});
|
||
|
} catch (error) {
|
||
|
console.log(error);
|
||
|
return null;
|
||
|
}
|
||
|
});
|
||
|
videoStream = yield getVideoStream();
|
||
|
if (!videoStream) {
|
||
|
videoEl.style.display = "none";
|
||
|
snapPhotoButton.style.display = "none";
|
||
|
recordVideoButton.style.display = "none";
|
||
|
switchCameraButton.style.display = "none";
|
||
|
filePicker2.style.display = "block";
|
||
|
}
|
||
|
const handleImageSelectChange = (file) => __async(this, null, function* () {
|
||
|
const chosenFile = file;
|
||
|
const bufferFile = yield chosenFile.arrayBuffer();
|
||
|
saveFile(bufferFile, false, chosenFile.name.split(" ").join("-"));
|
||
|
});
|
||
|
filePicker.onchange = () => handleImageSelectChange(filePicker.files[0]);
|
||
|
filePicker2.onchange = () => handleImageSelectChange(filePicker2.files[0]);
|
||
|
const view = this.app.workspace.getActiveViewOfType(import_obsidian.MarkdownView);
|
||
|
const saveFile = (file, isImage = false, fileName = "") => __async(this, null, function* () {
|
||
|
if (!fileName) {
|
||
|
const dateString = (new Date() + "").slice(4, 28).split(" ").join("_").split(":").join("-");
|
||
|
fileName = isImage ? `image_${dateString}.png` : `video_${dateString}.webm`;
|
||
|
}
|
||
|
if (!isImage)
|
||
|
new import_obsidian.Notice("Adding video to vault...");
|
||
|
const filePath = chosenFolderPath + "/" + fileName;
|
||
|
const folderExists = app.vault.getAbstractFileByPath(chosenFolderPath);
|
||
|
if (!folderExists)
|
||
|
yield app.vault.createFolder(chosenFolderPath);
|
||
|
const fileExists = app.vault.getAbstractFileByPath(filePath);
|
||
|
if (!fileExists)
|
||
|
yield app.vault.createBinary(filePath, file);
|
||
|
if (!view)
|
||
|
return new import_obsidian.Notice(`Saved to ${filePath}`);
|
||
|
const cursor = view.editor.getCursor();
|
||
|
view.editor.replaceRange(isImage ? `![${fileName}](${filePath})
|
||
|
` : `
|
||
|
![[${filePath}]]
|
||
|
`, cursor);
|
||
|
videoStream && videoStream.getTracks().forEach((track) => {
|
||
|
track.stop();
|
||
|
});
|
||
|
this.close();
|
||
|
});
|
||
|
switchCameraButton.onclick = () => __async(this, null, function* () {
|
||
|
cameraIndex = (cameraIndex + 1) % cameras.length;
|
||
|
videoStream = yield getVideoStream();
|
||
|
});
|
||
|
snapPhotoButton.onclick = () => {
|
||
|
const canvas = webCamContainer.createEl("canvas");
|
||
|
canvas.style.display = "none";
|
||
|
const { videoHeight, videoWidth } = videoEl;
|
||
|
canvas.height = videoHeight;
|
||
|
canvas.width = videoWidth;
|
||
|
canvas.getContext("2d").drawImage(videoEl, 0, 0, videoWidth, videoHeight);
|
||
|
canvas.toBlob((blob) => __async(this, null, function* () {
|
||
|
const bufferFile = yield blob.arrayBuffer();
|
||
|
saveFile(bufferFile, true);
|
||
|
}), "image/png");
|
||
|
};
|
||
|
videoEl.srcObject = videoStream;
|
||
|
recordVideoButton.onclick = () => __async(this, null, function* () {
|
||
|
switchCameraButton.disabled = true;
|
||
|
let isRecording = recorder && recorder.state === "recording";
|
||
|
if (isRecording)
|
||
|
recorder.stop();
|
||
|
isRecording = !isRecording;
|
||
|
recordVideoButton.innerText = isRecording ? "Stop Recording" : "Start Recording";
|
||
|
if (!recorder) {
|
||
|
recorder = new MediaRecorder(videoStream, {
|
||
|
mimeType: "video/webm"
|
||
|
});
|
||
|
}
|
||
|
recorder.ondataavailable = (e) => chunks.push(e.data);
|
||
|
recorder.onstop = (e) => __async(this, null, function* () {
|
||
|
const blob = new Blob(chunks, {
|
||
|
type: "audio/ogg; codecs=opus"
|
||
|
});
|
||
|
const bufferFile = yield blob.arrayBuffer();
|
||
|
saveFile(bufferFile, false);
|
||
|
});
|
||
|
recorder.start();
|
||
|
});
|
||
|
});
|
||
|
}
|
||
|
onClose() {
|
||
|
const { contentEl } = this;
|
||
|
contentEl.empty();
|
||
|
}
|
||
|
};
|
||
|
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsibWFpbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiaW1wb3J0IHsgQXBwLCBNYXJrZG93blZpZXcsIE1vZGFsLCBOb3RpY2UsIFBsdWdpbiB9IGZyb20gXCJvYnNpZGlhblwiO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBPYnNpZGlhbkNhbWVyYSBleHRlbmRzIFBsdWdpbiB7XG5cdGFzeW5jIG9ubG9hZCgpIHtcblx0XHR0aGlzLmFkZFJpYmJvbkljb24oXCJjYW1lcmFcIiwgXCJPYnNpZGlhbiBDYW1lcmFcIiwgKGV2dDogTW91c2VFdmVudCkgPT4ge1xuXHRcdFx0bmV3IENhbWVyYU1vZGFsKHRoaXMuYXBwKS5vcGVuKCk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLmFkZENvbW1hbmQoe1xuXHRcdFx0aWQ6IFwiT3BlbiBjYW1lcmEgbW9kYWxcIixcblx0XHRcdG5hbWU6IFwiT3BlbiBjYW1lcmEgbW9kYWwgLyBGaWxlIFBpY2tlclwiLFxuXHRcdFx0Y2FsbGJhY2s6ICgpID0+IHtcblx0XHRcdFx0bmV3IENhbWVyYU1vZGFsKHRoaXMuYXBwKS5vcGVuKCk7XG5cdFx0XHR9LFxuXHRcdH0pO1xuXHR9XG59XG5cbmNsYXNzIENhbWVyYU1vZGFsIGV4dGVuZHMgTW9kYWwge1xuXHRjb25zdHJ1Y3RvcihhcHA6IEFwcCkge1xuXHRcdHN1cGVyKGFwcCk7XG5cdH1cblxuXHRhc3luYyBvbk9wZW4oKSB7XG5cdFx0Y29uc3QgeyBjb250ZW50RWwgfSA9IHRoaXM7XG5cdFx0Y29uc3Qgd2ViQ2FtQ29udGFpbmVyID0gY29udGVudEVsLmNyZWF0ZURpdigpO1xuXHRcdC8vIGNvbnN0IHBUZXh0ID0gd2ViQ2FtQ29udGFpbmVyLmNyZWF0ZUVsKCdwJywgeyB0ZXh0OiAnZ2V0VmlkZW9TdHJlYW0gbm90IHlldCBzdXBwb3J0ZWQgb24gdGhpcyBkZXZpY2UuJyB9KTtcblx0XHQvLyBwVGV4dC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnXG5cdFx0Y29uc3QgdmlkZW9FbCA9IHdlYkNhbUNvbnRhaW5lci5jcmVhdGVFbChcInZpZGVvXCIpO1xuXHRcdHZpZGVvRWwuYXV0b3BsYXkgPSB0cnVlO1xuXHRcdHZpZGVvRWwubXV0ZWQgPSB0cnVlXG5cdFx0Y29uc3QgcmVjb3JkVmlkZW9CdXR0b24gPSB3ZWJDYW1Db250YWluZXIuY3JlYXRlRWwoXCJidXR0b25cIiwge1xuXHRcdFx0dGV4dDogXCJTdGFydCByZWNvcmRpbmdcIixcblx0XHR9KTtcblx0XHRjb25zdCBzd2l0Y2hDYW1lcmFCdXR0b24gPSB3ZWJDYW1Db250YWluZXIuY3JlYXRlRWwoXCJidXR0b25cIiwge1xuXHRcdFx0dGV4dDogXCJTd2l0Y2ggQ2FtZXJhXCIsXG5cdFx0fSk7XG5cdFx0Y29uc3Qgc25hcFBob3RvQnV0dG9uID0gd2ViQ2FtQ29udGFpbmVyLmNyZWF0ZUVsKFwiYnV0dG9uXCIsIHtcblx0XHRcdHRleHQ6IFwiVGFrZSBhIHNuYXBcIixcblx0XHR9KTtcblxuXHRcdGNvbnN0IGZpbGVQaWNrZXIgPSB3ZWJDYW1Db250YWluZXIuY3JlYXRlRWwoXCJpbnB1dFwiLCB7XG5cdFx0XHRwbGFjZWhvbGRlcjogXCJDaG9vc2UgaW1hZ2UgZmlsZSBmcm9tIHN5c3RlbVwiLFxuXHRcdFx0dHlwZTogXCJmaWxlXCIsXG5cdFx0fSk7XG5cdFx0ZmlsZVBpY2tlci5hY2NlcHQgPSBcImltYWdlLyosdmlkZW8vKlwiO1xuXHRcdGZpbGVQaWNrZXIuY2FwdHVyZSA9IFwiY2FtZXJhXCI7IC8vIGJhY2sgY2FtZXJhIGJ5IGRlZmF1bHQgZm9yIG1vYmlsZSBzY3JlZW5zXG5cblx0XHRjb25zdCBmaWxlUGlja2VyMiA9IHdlYkNhbUNvbnRhaW5lci5jcmVhdGVFbChcImlucHV0XCIsIHtcblx0XHRcdHBsYWNlaG9sZGVyOiBcIkNob29zZSBpbWFnZSBmaWxlIGZyb20gc3lzdGVtXCIsXG5cdFx0XHR0eXBlOiBcImZpbGVcIixcblx0XHR9KTtcblx0XHRmaWxlUGlja2VyMi5hY2NlcHQgPSBcImltYWdlLypcIjtcblx0XHRmaWxlUGlja2VyMi5jYXB0dXJlID0gXCJjYW1lcmFcIjsgLy8gYmFjayBjYW1lcmEgYnkgZGVmYXVsdCBmb3IgbW9iaWxlIHNjcmVlbnNcblx0XHQvLyBmaWxlUGlja2VyMi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnXG5cblxuXHRcdGNvbnN0IGNob3NlbkZvbGRlclBhdGggPSBcImF0dGFjaG1lbnRzL3NuYXBzXCI7XG5cdFx0Y29uc3QgY2h1bmtzOiBCbG9iUGFydFtdID0gW107XG5cdFx0bGV0IHJlY29yZGVyOiBNZWRpYVJlY29yZGVyID0gbnVsbDtcblx0XHRsZXQgdmlkZW9TdHJlYW06IE1lZGlhU3RyZWFtID0gbnVsbDtcblxuXHRcdGNvbnN0IGNhbWVyYXMgPSAoXG5cdFx0XHRhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmVudW1lcmF0ZURldmljZXMoKVxuXHRcdCkuZmlsdGVyKChkKSA9PiBkLmtpbmQgPT09IFwidmlkZW9pbnB1dFwiKTtcblxuXHRcdGlmIChjYW1lcmFzLmxlbmd0aCA8PSAxKSBzd2l0Y2hDYW1lcmFCdXR0b24uc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuXHRcdGxldCBjYW1lcmFJbmRleCA9IDA7XG5cblx0XHRjb25zdCBnZXRWaWRlb1N0cmVhbSA9IGFzeW5jICgpID0+IHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdHJldHVybiBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG5cdFx0XHRcdFx0dmlkZW86IHsgZGV2aWNlSWQ6IGNhbWVyYXNbY2FtZXJhSW5kZXhdLmRldmljZUlkIH0sXG5cdFx0XHRcdFx0YXVkaW86IHRydWUsXG5cdFx0XHRcdH0pO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0Y29uc29sZS5sb2coZXJyb3IpO1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dmlkZW9TdHJlYW0gPSBhd2FpdCBnZXRWaWRlb1N0cmVhbSgpO1xuXHRcdGlmICghdmlkZW9TdHJlYW0pIHtcblx0XHRcdHZpZGVvRWwuc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuXHRcdFx0Ly8gcFRleHQuc3R5bGUuZGlzcGxheSA9ICdibG9jaydcblx0XHRcdHNuYXBQaG90b0J1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnXG5cdFx0XHRyZWNvcmRWaWRlb0J1dHRvbi5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnXG5cdFx0XHRzd2l0Y2hDYW1lcmFCdXR0b24uc3R5bGUuZGlzcGxheSA9ICdub25lJ1xuXHRcdFx0ZmlsZVBpY2tlcjIuc3R5bGUuZGlzcGxheSA9ICdibG9jaydcblx0XHR9XG5cblx0XHRjb25zdCBoYW5kbGVJbWFnZVNlbGVjdENoYW5nZSA9I
|