mirror of
https://github.com/koush/scrypted.git
synced 2026-03-20 16:40:24 +00:00
global: rename FFMpeg to FFmpeg
This commit is contained in:
@@ -35,12 +35,12 @@ export const FFMPEG_FRAGMENTED_MP4_OUTPUT_ARGS = [
|
||||
'-f', 'mp4',
|
||||
];
|
||||
|
||||
export interface FFMpegFragmentedMP4Session {
|
||||
export interface FFmpegFragmentedMP4Session {
|
||||
cp: ChildProcess;
|
||||
generator: AsyncGenerator<MP4Atom>;
|
||||
}
|
||||
|
||||
export async function startFFMPegFragmentedMP4Session(inputArguments: string[], audioOutputArgs: string[], videoOutputArgs: string[], console: Console): Promise<FFMpegFragmentedMP4Session> {
|
||||
export async function startFFMPegFragmentedMP4Session(inputArguments: string[], audioOutputArgs: string[], videoOutputArgs: string[], console: Console): Promise<FFmpegFragmentedMP4Session> {
|
||||
const args = inputArguments.slice();
|
||||
args.push(
|
||||
...videoOutputArgs,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { createServer, Server } from 'net';
|
||||
import child_process, { StdioOptions } from 'child_process';
|
||||
import { ChildProcess } from 'child_process';
|
||||
import { FFMpegInput } from '@scrypted/sdk/types';
|
||||
import { FFmpegInput } from '@scrypted/sdk/types';
|
||||
import { bind, bindZero, listenZero, listenZeroSingleClient } from './listen-cluster';
|
||||
import { EventEmitter } from 'events';
|
||||
import sdk, { RequestMediaStreamOptions, ResponseMediaStreamOptions } from "@scrypted/sdk";
|
||||
@@ -113,7 +113,7 @@ export function setupActivityTimer(container: string, kill: () => void, events:
|
||||
}
|
||||
|
||||
|
||||
export async function startParserSession<T extends string>(ffmpegInput: FFMpegInput, options: ParserOptions<T>): Promise<ParserSession<T>> {
|
||||
export async function startParserSession<T extends string>(ffmpegInput: FFmpegInput, options: ParserOptions<T>): Promise<ParserSession<T>> {
|
||||
const { console } = options;
|
||||
|
||||
let ffmpegIncomingConnectionTimeout: NodeJS.Timeout;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import child_process from 'child_process';
|
||||
import { listenZeroSingleClient } from "./listen-cluster";
|
||||
import { ffmpegLogInitialOutput, safePrintFFmpegArguments } from "./media-helpers";
|
||||
import sdk, { FFMpegInput, ScryptedMimeTypes, MediaObject, RTCAVSignalingSetup, RTCSignalingChannel, RTCSignalingSession, ScryptedDevice, ScryptedInterface, VideoCamera, RTCSignalingOptions } from "@scrypted/sdk";
|
||||
import sdk, { FFmpegInput, ScryptedMimeTypes, MediaObject, RTCAVSignalingSetup, RTCSignalingChannel, RTCSignalingSession, ScryptedDevice, ScryptedInterface, VideoCamera, RTCSignalingOptions } from "@scrypted/sdk";
|
||||
import { RpcPeer } from "../../server/src/rpc";
|
||||
|
||||
const { mediaManager } = sdk;
|
||||
@@ -34,7 +34,7 @@ function initalizeWebRtc() {
|
||||
Object.assign(global, wrtc);
|
||||
}
|
||||
|
||||
export async function startRTCPeerConnectionFFmpegInput(ffInput: FFMpegInput, console: Console, options?: {
|
||||
export async function startRTCPeerConnectionFFmpegInput(ffInput: FFmpegInput, console: Console, options?: {
|
||||
maxWidth: number,
|
||||
}): Promise<RTCPeerConnection> {
|
||||
initalizeWebRtc();
|
||||
|
||||
@@ -7,7 +7,7 @@ import readline from 'readline-sync';
|
||||
import https from 'https';
|
||||
import mkdirp from 'mkdirp';
|
||||
import { installServe, serveMain } from './service';
|
||||
import { connectScryptedClient, ScryptedMimeTypes, FFMpegInput } from '../../client/src/index';
|
||||
import { connectScryptedClient, ScryptedMimeTypes, FFmpegInput } from '../../client/src/index';
|
||||
import semver from 'semver';
|
||||
import child_process from 'child_process';
|
||||
|
||||
@@ -145,7 +145,7 @@ async function main() {
|
||||
}
|
||||
else if (process.argv[2] === 'ffplay') {
|
||||
const { sdk, pendingResult } = await runCommand();
|
||||
const ffinput = await sdk.mediaManager.convertMediaObjectToJSON<FFMpegInput>(await pendingResult, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffinput = await sdk.mediaManager.convertMediaObjectToJSON<FFmpegInput>(await pendingResult, ScryptedMimeTypes.FFmpegInput);
|
||||
console.log(ffinput);
|
||||
child_process.spawn('ffplay', ffinput.inputArguments, {
|
||||
stdio: 'inherit',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { MediaObject, Camera, ScryptedInterface, Setting, ScryptedDeviceType, Intercom, FFMpegInput, ScryptedMimeTypes, PictureOptions, VideoCameraConfiguration, MediaStreamOptions, VideoRecorder, RequestRecordingStreamOptions } from "@scrypted/sdk";
|
||||
import sdk, { MediaObject, Camera, ScryptedInterface, Setting, ScryptedDeviceType, Intercom, FFmpegInput, ScryptedMimeTypes, PictureOptions, VideoCameraConfiguration, MediaStreamOptions, VideoRecorder, RequestRecordingStreamOptions } from "@scrypted/sdk";
|
||||
import { Stream, PassThrough } from "stream";
|
||||
import { AmcrestCameraClient, AmcrestEvent, amcrestHttpsAgent } from "./amcrest-api";
|
||||
import { RtspSmartCamera, RtspProvider, Destroyable, UrlMediaStreamOptions } from "../../rtsp/src/rtsp";
|
||||
@@ -408,7 +408,7 @@ class AmcrestCamera extends RtspSmartCamera implements VideoCameraConfiguration,
|
||||
const channel = this.getRtspChannel() || '1';
|
||||
|
||||
const buffer = await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = JSON.parse(buffer.toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse(buffer.toString()) as FFmpegInput;
|
||||
|
||||
const args = ffmpegInput.inputArguments.slice();
|
||||
args.unshift('-hide_banner');
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { BinarySensor, Camera, Device, DeviceDiscovery, DeviceProvider, FFMpegInput, Intercom, MediaObject, MediaStreamOptions, MotionSensor, PictureOptions, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk';
|
||||
import { BinarySensor, Camera, Device, DeviceDiscovery, DeviceProvider, FFmpegInput, Intercom, MediaObject, MediaStreamOptions, MotionSensor, PictureOptions, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk';
|
||||
import sdk from '@scrypted/sdk';
|
||||
import { StorageSettings } from '../../../common/src/settings';
|
||||
|
||||
@@ -22,7 +22,7 @@ class SampleCameraDevice extends ScryptedDeviceBase implements Intercom, Camera,
|
||||
}
|
||||
|
||||
async getVideoStream(options?: MediaStreamOptions): Promise<MediaObject> {
|
||||
let ffmpegInput: FFMpegInput;
|
||||
let ffmpegInput: FFmpegInput;
|
||||
|
||||
// the input arguemnt to ffmpeg can be any valid ffmpeg input argument.
|
||||
// if its an url, note below that it is.
|
||||
@@ -44,7 +44,7 @@ class SampleCameraDevice extends ScryptedDeviceBase implements Intercom, Camera,
|
||||
|
||||
|
||||
async startIntercom(media: MediaObject): Promise<void> {
|
||||
const ffmpegInput: FFMpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput)).toString());
|
||||
const ffmpegInput: FFmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput)).toString());
|
||||
// something wants to start playback on the camera speaker.
|
||||
// use their ffmpeg input arguments to spawn ffmpeg to do playback.
|
||||
// some implementations read the data from an ffmpeg pipe output and POST to a url (like unifi/amcrest).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { EventListener, EventListenerRegister, FFMpegInput, LockState, MediaObject, MediaStreamOptions, ScryptedDevice, ScryptedDeviceBase, ScryptedInterface, ScryptedInterfaceDescriptors, ScryptedMimeTypes, VideoCamera } from "@scrypted/sdk";
|
||||
import { EventListener, EventListenerRegister, FFmpegInput, LockState, MediaObject, MediaStreamOptions, ScryptedDevice, ScryptedDeviceBase, ScryptedInterface, ScryptedInterfaceDescriptors, ScryptedMimeTypes, VideoCamera } from "@scrypted/sdk";
|
||||
import sdk from "@scrypted/sdk";
|
||||
import { startParserSession, ParserSession, createParserRebroadcaster, Rebroadcaster, createRebroadcaster } from "@scrypted/common/src/ffmpeg-rebroadcast";
|
||||
import { createMpegTsParser, StreamParser } from "@scrypted/common/src/stream-parser";
|
||||
@@ -56,11 +56,11 @@ function createVideoCamera(devices: VideoCamera[], console: Console): VideoCamer
|
||||
const args = await Promise.allSettled(devices.map(async (device) => {
|
||||
const mo = await device.getVideoStream();
|
||||
const buffer = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = JSON.parse(buffer.toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse(buffer.toString()) as FFmpegInput;
|
||||
return ffmpegInput;
|
||||
}));
|
||||
|
||||
const inputs = args.map(arg => (arg as PromiseFulfilledResult<FFMpegInput>).value).filter(input => !!input);
|
||||
const inputs = args.map(arg => (arg as PromiseFulfilledResult<FFmpegInput>).value).filter(input => !!input);
|
||||
|
||||
if (!inputs.length)
|
||||
throw new Error('no inputs');
|
||||
@@ -77,7 +77,7 @@ function createVideoCamera(devices: VideoCamera[], console: Console): VideoCamer
|
||||
'nullsrc=size=1920x1080 [base];'
|
||||
];
|
||||
|
||||
const filteredInput: FFMpegInput = {
|
||||
const filteredInput: FFmpegInput = {
|
||||
url: undefined,
|
||||
inputArguments: [],
|
||||
};
|
||||
@@ -165,7 +165,7 @@ function createVideoCamera(devices: VideoCamera[], console: Console): VideoCamer
|
||||
|
||||
const ret = await sessionPromise;
|
||||
const {url} = ret.rebroadcaster;
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url,
|
||||
container: 'mpegts',
|
||||
inputArguments: [
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, MediaStreamOptions, ScryptedInterface, FFMpegInput, Camera, PictureOptions, SettingValue, DeviceCreator, DeviceCreatorSettings, ResponseMediaStreamOptions } from "@scrypted/sdk";
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, MediaStreamOptions, ScryptedInterface, FFmpegInput, Camera, PictureOptions, SettingValue, DeviceCreator, DeviceCreatorSettings, ResponseMediaStreamOptions } from "@scrypted/sdk";
|
||||
import AxiosDigestAuth from '@koush/axios-digest-auth';
|
||||
import https from 'https';
|
||||
import { randomBytes } from "crypto";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { FFMpegInput, Intercom, MediaObject, PictureOptions, ScryptedInterface, ScryptedMimeTypes, Setting, SettingValue } from "@scrypted/sdk";
|
||||
import sdk, { FFmpegInput, Intercom, MediaObject, PictureOptions, ScryptedInterface, ScryptedMimeTypes, Setting, SettingValue } from "@scrypted/sdk";
|
||||
import { CameraProviderBase, CameraBase, UrlMediaStreamOptions } from "./common";
|
||||
import { StorageSettings } from "../../../common/src/settings";
|
||||
import { ffmpegLogInitialOutput, safePrintFFmpegArguments } from "../../../common/src/media-helpers";
|
||||
@@ -37,7 +37,7 @@ class FFmpegCamera extends CameraBase<UrlMediaStreamOptions> implements Intercom
|
||||
|
||||
async startIntercom(media: MediaObject): Promise<void> {
|
||||
const buffer = await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput: FFMpegInput = JSON.parse(buffer.toString());
|
||||
const ffmpegInput: FFmpegInput = JSON.parse(buffer.toString());
|
||||
|
||||
const args = ffmpegInput.inputArguments.slice();
|
||||
args.push(...this.storageSettings.values.ffmpegOutput.split(' '));
|
||||
@@ -111,7 +111,7 @@ class FFmpegCamera extends CameraBase<UrlMediaStreamOptions> implements Intercom
|
||||
if (!ffmpegInput)
|
||||
throw new Error('video streams not set up or no longer exists.');
|
||||
|
||||
const ret: FFMpegInput = {
|
||||
const ret: FFmpegInput = {
|
||||
url: options.url,
|
||||
inputArguments: ffmpegInput.split(' '),
|
||||
mediaStreamOptions: options,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { DeviceManifest, DeviceProvider, HttpRequest, HttpRequestHandler, HttpResponse, HumiditySensor, MediaObject, MotionSensor, OauthClient, Refresh, ScryptedDeviceType, ScryptedInterface, Setting, Settings, TemperatureSetting, TemperatureUnit, Thermometer, ThermostatMode, VideoCamera, MediaStreamOptions, BinarySensor, DeviceInformation, RTCAVSignalingSetup, Camera, PictureOptions, ObjectsDetected, ObjectDetector, ObjectDetectionTypes, FFMpegInput, RequestMediaStreamOptions, Readme, RTCSignalingChannel, RTCSessionControl, RTCSignalingSession, ResponseMediaStreamOptions, RTCSignalingOptions, RTCSignalingSendIceCandidate } from '@scrypted/sdk';
|
||||
import sdk, { DeviceManifest, DeviceProvider, HttpRequest, HttpRequestHandler, HttpResponse, HumiditySensor, MediaObject, MotionSensor, OauthClient, Refresh, ScryptedDeviceType, ScryptedInterface, Setting, Settings, TemperatureSetting, TemperatureUnit, Thermometer, ThermostatMode, VideoCamera, MediaStreamOptions, BinarySensor, DeviceInformation, RTCAVSignalingSetup, Camera, PictureOptions, ObjectsDetected, ObjectDetector, ObjectDetectionTypes, FFmpegInput, RequestMediaStreamOptions, Readme, RTCSignalingChannel, RTCSessionControl, RTCSignalingSession, ResponseMediaStreamOptions, RTCSignalingOptions, RTCSignalingSendIceCandidate } from '@scrypted/sdk';
|
||||
import { ScryptedDeviceBase } from '@scrypted/sdk';
|
||||
import qs from 'query-string';
|
||||
import ClientOAuth2 from 'client-oauth2';
|
||||
@@ -299,7 +299,7 @@ class NestCamera extends ScryptedDeviceBase implements Readme, Camera, VideoCame
|
||||
const mso = getSdmRtspMediaStreamOptions();
|
||||
this.addRefreshOptions(trackerId, mso);
|
||||
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url: undefined,
|
||||
mediaStreamOptions: mso,
|
||||
inputArguments: undefined,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, MediaStreamOptions, ScryptedInterface, FFMpegInput, Camera, PictureOptions, SettingValue, DeviceCreator, DeviceCreatorSettings } from "@scrypted/sdk";
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, ScryptedDeviceType, VideoCamera, MediaObject, MediaStreamOptions, ScryptedInterface, FFmpegInput, Camera, PictureOptions, SettingValue, DeviceCreator, DeviceCreatorSettings } from "@scrypted/sdk";
|
||||
import { recommendRebroadcast } from "./recommend";
|
||||
import AxiosDigestAuth from '@koush/axios-digest-auth';
|
||||
import https from 'https';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { FFMpegInput, MediaObject, MediaStreamOptions, Setting, SettingValue } from "@scrypted/sdk";
|
||||
import sdk, { FFmpegInput, MediaObject, MediaStreamOptions, Setting, SettingValue } from "@scrypted/sdk";
|
||||
import child_process, { ChildProcess } from "child_process";
|
||||
import { CameraProviderBase, CameraBase, UrlMediaStreamOptions } from "./common";
|
||||
// import {} from "../../../common/src/stream-parser"
|
||||
@@ -131,7 +131,7 @@ class GStreamerCamera extends CameraBase<MediaStreamOptions> {
|
||||
}, 30000);
|
||||
const port = await listenZero(server);
|
||||
|
||||
const ret: FFMpegInput = {
|
||||
const ret: FFmpegInput = {
|
||||
url: undefined,
|
||||
inputArguments: [
|
||||
'-f',
|
||||
|
||||
@@ -71,7 +71,7 @@ export class CameraMixin extends HomekitMixin<any> {
|
||||
key: 'transcodeRecording',
|
||||
type: 'boolean',
|
||||
value: (this.storage.getItem('transcodeRecording') === 'true').toString(),
|
||||
description: 'Use FFMpeg to transcode recordings to a format supported by HomeKit Secure Video.',
|
||||
description: 'Use FFmpeg to transcode recordings to a format supported by HomeKit Secure Video.',
|
||||
});
|
||||
|
||||
showTranscodeArgs = showTranscodeArgs || this.storage.getItem('transcodeRecording') === 'true';
|
||||
@@ -83,7 +83,7 @@ export class CameraMixin extends HomekitMixin<any> {
|
||||
type: 'boolean',
|
||||
key: 'transcodeStreaming',
|
||||
value: (this.storage.getItem('transcodeStreaming') === 'true').toString(),
|
||||
description: 'Use FFMpeg to transcode streaming to a format supported by HomeKit.',
|
||||
description: 'Use FFmpeg to transcode streaming to a format supported by HomeKit.',
|
||||
});
|
||||
|
||||
const transcodeEnabledValues = [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { listenZero } from "@scrypted/common/src/listen-cluster";
|
||||
import { FFMpegInput } from "@scrypted/sdk";
|
||||
import { FFmpegInput } from "@scrypted/sdk";
|
||||
import { Socket, SocketType } from "dgram";
|
||||
import { createServer, Server } from "net";
|
||||
import { AudioStreamingCodecType, AudioInfo, AudioStreamingSamplerate } from "../hap";
|
||||
@@ -11,7 +11,7 @@ function pickPort() {
|
||||
export class HomeKitRtpSink {
|
||||
heartbeatTimer: NodeJS.Timeout;
|
||||
|
||||
constructor(public server: Server, public rtpPort: number, public ffmpegInput: FFMpegInput, public console: Console) {
|
||||
constructor(public server: Server, public rtpPort: number, public ffmpegInput: FFmpegInput, public console: Console) {
|
||||
}
|
||||
|
||||
// Send a regular heartbeat to FFmpeg to ensure the pipe remains open and the process alive.
|
||||
@@ -143,7 +143,7 @@ export async function startRtpSink(socketType: SocketType, address: string, srtp
|
||||
});
|
||||
const sdpServerPort = await listenZero(server);
|
||||
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url: undefined,
|
||||
mediaStreamOptions: {
|
||||
id: undefined,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
import sdk, { FFMpegInput, MediaObject, VideoClip, VideoClipOptions } from '@scrypted/sdk';
|
||||
import sdk, { FFmpegInput, MediaObject, VideoClip, VideoClipOptions } from '@scrypted/sdk';
|
||||
import path from 'path';
|
||||
import fs from 'fs';
|
||||
import mkdirp from 'mkdirp';
|
||||
@@ -177,7 +177,7 @@ export async function getVideoClipThumbnail(videoClipId: string): Promise<MediaO
|
||||
jpeg = fs.readFileSync(thumbnailPath);
|
||||
}
|
||||
else {
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url: undefined,
|
||||
inputArguments: [
|
||||
'-ss', '00:00:04',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { FFMpegFragmentedMP4Session, parseFragmentedMP4, startFFMPegFragmentedMP4Session } from '@scrypted/common/src/ffmpeg-mp4-parser-session';
|
||||
import { FFmpegFragmentedMP4Session, parseFragmentedMP4, startFFMPegFragmentedMP4Session } from '@scrypted/common/src/ffmpeg-mp4-parser-session';
|
||||
import { safeKillFFmpeg } from '@scrypted/common/src/media-helpers';
|
||||
import sdk, { AudioSensor, FFMpegInput, MotionSensor, ScryptedDevice, ScryptedInterface, ScryptedMimeTypes, VideoCamera } from '@scrypted/sdk';
|
||||
import sdk, { AudioSensor, FFmpegInput, MotionSensor, ScryptedDevice, ScryptedInterface, ScryptedMimeTypes, VideoCamera } from '@scrypted/sdk';
|
||||
import fs from 'fs';
|
||||
import mkdirp from 'mkdirp';
|
||||
import net from 'net';
|
||||
@@ -36,7 +36,7 @@ export async function* handleFragmentsRequests(device: ScryptedDevice & VideoCam
|
||||
prebuffer: configuration.mediaContainerConfiguration.prebufferLength,
|
||||
container: 'mp4',
|
||||
});
|
||||
const ffmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput)).toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput)).toString()) as FFmpegInput;
|
||||
if (!ffmpegInput.mediaStreamOptions?.prebuffer) {
|
||||
log.a(`${device.name} is not prebuffered. Please install and enable the Rebroadcast plugin.`);
|
||||
}
|
||||
@@ -47,7 +47,7 @@ export async function* handleFragmentsRequests(device: ScryptedDevice & VideoCam
|
||||
const transcodeRecording = storage.getItem('transcodeRecording') === 'true';
|
||||
const incompatibleStream = noAudio || transcodeRecording || isDefinitelyNotAAC;
|
||||
|
||||
let session: FFMpegFragmentedMP4Session & { socket?: Duplex };
|
||||
let session: FFmpegFragmentedMP4Session & { socket?: Duplex };
|
||||
|
||||
if (ffmpegInput.container === 'mp4' && ffmpegInput.url.startsWith('tcp://') && !incompatibleStream) {
|
||||
console.log('prebuffer is tcp/mp4/h264/aac compatible. using direct tcp.');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createBindZero } from '@scrypted/common/src/listen-cluster';
|
||||
import { ffmpegLogInitialOutput, safePrintFFmpegArguments } from '@scrypted/common/src/media-helpers';
|
||||
import sdk, { FFMpegInput, MediaStreamDestination, RequestMediaStreamOptions, ScryptedDevice, ScryptedMimeTypes, VideoCamera } from '@scrypted/sdk';
|
||||
import sdk, { FFmpegInput, MediaStreamDestination, RequestMediaStreamOptions, ScryptedDevice, ScryptedMimeTypes, VideoCamera } from '@scrypted/sdk';
|
||||
import child_process from 'child_process';
|
||||
import { RtpPacket } from '../../../../../external/werift/packages/rtp/src/rtp/rtp';
|
||||
import { ProtectionProfileAes128CmHmacSha1_80 } from '../../../../../external/werift/packages/rtp/src/srtp/const';
|
||||
@@ -27,12 +27,12 @@ export async function startCameraStreamFfmpeg(device: ScryptedDevice & VideoCame
|
||||
// option, but not sure it matters since AAC-ELD is no longer in use.
|
||||
let audiomtu = 400;
|
||||
|
||||
const videoInput = await mediaManager.convertMediaObjectToJSON<FFMpegInput>(await device.getVideoStream(requestOptions), ScryptedMimeTypes.FFmpegInput);
|
||||
const videoInput = await mediaManager.convertMediaObjectToJSON<FFmpegInput>(await device.getVideoStream(requestOptions), ScryptedMimeTypes.FFmpegInput);
|
||||
session.mediaStreamOptions = videoInput.mediaStreamOptions;
|
||||
// test code path that allows using two ffmpeg processes. did not see
|
||||
// any notable benefit with a prebuffer, which allows the ffmpeg analysis for key frame
|
||||
// to immediately finish. ffmpeg will only start sending on a key frame.
|
||||
// const audioInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(await device.getVideoStream(selectedStream), ScryptedMimeTypes.FFmpegInput)).toString()) as FFMpegInput;
|
||||
// const audioInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(await device.getVideoStream(selectedStream), ScryptedMimeTypes.FFmpegInput)).toString()) as FFmpegInput;
|
||||
const audioInput = videoInput;
|
||||
|
||||
const videoKey = Buffer.concat([session.prepareRequest.video.srtp_key, session.prepareRequest.video.srtp_salt]);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { MediaObject, Intercom, FFMpegInput, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import sdk, { MediaObject, Intercom, FFmpegInput, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import { RtspSmartCamera } from "../../rtsp/src/rtsp";
|
||||
import { parseSemicolonDelimited, RtspClient } from "@scrypted/common/src/rtsp-server";
|
||||
import { findTrack } from "@scrypted/common/src/sdp-utils";
|
||||
@@ -106,7 +106,7 @@ export class OnvifIntercom implements Intercom {
|
||||
const serverPorts = server_port.split('-');
|
||||
const serverRtp = parseInt(serverPorts[0]);
|
||||
|
||||
const ffmpegInput = await mediaManager.convertMediaObjectToJSON<FFMpegInput>(media, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = await mediaManager.convertMediaObjectToJSON<FFmpegInput>(media, ScryptedMimeTypes.FFmpegInput);
|
||||
|
||||
const availableCodecs = [...parseCodecs(audioBackchannel.section)];
|
||||
let match: CodecMatch;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FFMpegInput, MediaObject, ObjectDetection, ObjectDetectionModel, ObjectDetectionSession, ObjectsDetected, ScryptedDeviceBase, ScryptedInterface, ScryptedMimeTypes } from '@scrypted/sdk';
|
||||
import { FFmpegInput, MediaObject, ObjectDetection, ObjectDetectionModel, ObjectDetectionSession, ObjectsDetected, ScryptedDeviceBase, ScryptedInterface, ScryptedMimeTypes } from '@scrypted/sdk';
|
||||
import sdk from '@scrypted/sdk';
|
||||
import { ffmpegLogInitialOutput } from "../../../common/src/media-helpers";
|
||||
|
||||
@@ -67,7 +67,7 @@ class PamDiff extends ScryptedDeviceBase implements ObjectDetection {
|
||||
}
|
||||
|
||||
const ffmpeg = await mediaManager.getFFmpegPath();
|
||||
const ffmpegInput: FFMpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(
|
||||
const ffmpegInput: FFmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(
|
||||
mediaObject,
|
||||
ScryptedMimeTypes.FFmpegInput
|
||||
)).toString());
|
||||
|
||||
@@ -11,7 +11,7 @@ import { StorageSettings } from '@scrypted/common/src/settings';
|
||||
import { SettingsMixinDeviceBase, SettingsMixinDeviceOptions } from "@scrypted/common/src/settings-mixin";
|
||||
import { sleep } from '@scrypted/common/src/sleep';
|
||||
import { createFragmentedMp4Parser, createMpegTsParser, parseMp4StreamChunks, StreamChunk, StreamParser } from '@scrypted/common/src/stream-parser';
|
||||
import sdk, { BufferConverter, FFMpegInput, MediaObject, MediaStreamOptions, MixinProvider, RequestMediaStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera, VideoCameraConfiguration } from '@scrypted/sdk';
|
||||
import sdk, { BufferConverter, FFmpegInput, MediaObject, MediaStreamOptions, MixinProvider, RequestMediaStreamOptions, ResponseMediaStreamOptions, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera, VideoCameraConfiguration } from '@scrypted/sdk';
|
||||
import crypto from 'crypto';
|
||||
import dgram from 'dgram';
|
||||
import net from 'net';
|
||||
@@ -606,7 +606,7 @@ class PrebufferSession {
|
||||
}
|
||||
else {
|
||||
const moBuffer = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = JSON.parse(moBuffer.toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse(moBuffer.toString()) as FFmpegInput;
|
||||
sessionMso = ffmpegInput.mediaStreamOptions;
|
||||
|
||||
const parser = this.getParser(rtspMode, muxingMp4, ffmpegInput.mediaStreamOptions);
|
||||
@@ -726,7 +726,7 @@ class PrebufferSession {
|
||||
})
|
||||
.then(async (stream) => {
|
||||
const extraInputArguments = this.storage.getItem(this.ffmpegInputArgumentsKey) || DEFAULT_FFMPEG_INPUT_ARGUMENTS;
|
||||
const ffmpegInput = await mediaManager.convertMediaObjectToJSON<FFMpegInput>(stream, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = await mediaManager.convertMediaObjectToJSON<FFmpegInput>(stream, ScryptedMimeTypes.FFmpegInput);
|
||||
ffmpegInput.inputArguments.unshift(...extraInputArguments.split(' '));
|
||||
const mp4Session = await startFFMPegFragmentedMP4Session(ffmpegInput.inputArguments, acodec, vcodec, this.console);
|
||||
|
||||
@@ -804,7 +804,7 @@ class PrebufferSession {
|
||||
return;
|
||||
const mo = await this.mixinDevice.getVideoStream(mso);
|
||||
const moBuffer = await mediaManager.convertMediaObjectToBuffer(mo, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = JSON.parse(moBuffer.toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse(moBuffer.toString()) as FFmpegInput;
|
||||
mso = ffmpegInput.mediaStreamOptions;
|
||||
|
||||
scheduleRefresh(mso);
|
||||
@@ -1115,7 +1115,7 @@ class PrebufferSession {
|
||||
|
||||
const length = Math.max(500000, available).toString();
|
||||
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url,
|
||||
container,
|
||||
inputArguments: [
|
||||
@@ -1490,7 +1490,7 @@ class PrebufferProvider extends AutoenableMixinProvider implements MixinProvider
|
||||
if (!u.protocol.startsWith('tcp'))
|
||||
throw new Error('rfc4751 url must be tcp');
|
||||
const { clientPromise, url: clientUrl } = await listenZeroSingleClient();
|
||||
const ffmpeg: FFMpegInput = {
|
||||
const ffmpeg: FFmpegInput = {
|
||||
url: clientUrl,
|
||||
inputArguments: [
|
||||
"-rtsp_transport", "tcp",
|
||||
|
||||
@@ -4,7 +4,7 @@ import { connectRTCSignalingClients } from '@scrypted/common/src/rtc-connect';
|
||||
import { RtspServer } from '@scrypted/common/src/rtsp-server';
|
||||
import { addTrackControls, replacePorts } from '@scrypted/common/src/sdp-utils';
|
||||
import { StorageSettings } from '@scrypted/common/src/settings';
|
||||
import sdk, { BinarySensor, Camera, Device, DeviceDiscovery, DeviceProvider, FFMpegInput, Intercom, MediaObject, MotionSensor, OnOff, PictureOptions, RequestMediaStreamOptions, RequestPictureOptions, ResponseMediaStreamOptions, RTCAVSignalingSetup, RTCSessionControl, RTCSignalingChannel, RTCSignalingSendIceCandidate, RTCSignalingSession, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk';
|
||||
import sdk, { BinarySensor, Camera, Device, DeviceDiscovery, DeviceProvider, FFmpegInput, Intercom, MediaObject, MotionSensor, OnOff, PictureOptions, RequestMediaStreamOptions, RequestPictureOptions, ResponseMediaStreamOptions, RTCAVSignalingSetup, RTCSessionControl, RTCSignalingChannel, RTCSignalingSendIceCandidate, RTCSignalingSession, ScryptedDeviceBase, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk';
|
||||
import child_process, { ChildProcess } from 'child_process';
|
||||
import dgram from 'dgram';
|
||||
import { RtcpReceiverInfo, RtcpRrPacket } from '../../../external/werift/packages/rtp/src/rtcp/rr';
|
||||
@@ -82,7 +82,7 @@ class RingCameraDevice extends ScryptedDeviceBase implements Intercom, Settings,
|
||||
rtpDescription: RtpDescription;
|
||||
audioOutForwarder: dgram.Socket;
|
||||
audioOutProcess: ChildProcess;
|
||||
ffmpegInput: FFMpegInput;
|
||||
ffmpegInput: FFmpegInput;
|
||||
refreshTimeout: NodeJS.Timeout;
|
||||
picturePromise: RefreshPromise<Buffer>;
|
||||
|
||||
@@ -100,7 +100,7 @@ class RingCameraDevice extends ScryptedDeviceBase implements Intercom, Settings,
|
||||
|
||||
this.stopIntercom();
|
||||
|
||||
const ffmpegInput: FFMpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput)).toString());
|
||||
const ffmpegInput: FFmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput)).toString());
|
||||
|
||||
const ringRtpOptions = this.rtpDescription;
|
||||
let cameraSpeakerActive = false;
|
||||
@@ -344,7 +344,7 @@ class RingCameraDevice extends ScryptedDeviceBase implements Intercom, Settings,
|
||||
}
|
||||
});
|
||||
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url: playbackUrl,
|
||||
mediaStreamOptions: Object.assign(this.getSipMediaStreamOptions(), {
|
||||
refreshAt: Date.now() + STREAM_TIMEOUT,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { Setting, MediaObject, ScryptedInterface, FFMpegInput, PictureOptions, SettingValue, MediaStreamOptions, ResponseMediaStreamOptions, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import sdk, { Setting, MediaObject, ScryptedInterface, FFmpegInput, PictureOptions, SettingValue, MediaStreamOptions, ResponseMediaStreamOptions, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import { EventEmitter } from "stream";
|
||||
import { CameraProviderBase, CameraBase, UrlMediaStreamOptions } from "../../ffmpeg-camera/src/common";
|
||||
import url from 'url';
|
||||
@@ -72,7 +72,7 @@ export class RtspCamera extends CameraBase<UrlMediaStreamOptions> {
|
||||
}
|
||||
|
||||
createFfmpegMediaObject(stringUrl: string, vso: ResponseMediaStreamOptions) {
|
||||
const ret: FFMpegInput = {
|
||||
const ret: FFmpegInput = {
|
||||
url: stringUrl,
|
||||
inputArguments: [
|
||||
"-rtsp_transport", this.getRtspTransport(),
|
||||
|
||||
@@ -19,7 +19,7 @@ from pipeline import run_pipeline
|
||||
|
||||
from gi.repository import Gst
|
||||
|
||||
from scrypted_sdk.types import FFMpegInput, MediaObject, ObjectDetection, ObjectDetectionModel, ObjectDetectionSession, ObjectsDetected, ScryptedInterface, ScryptedMimeTypes
|
||||
from scrypted_sdk.types import FFmpegInput, MediaObject, ObjectDetection, ObjectDetectionModel, ObjectDetectionSession, ObjectsDetected, ScryptedInterface, ScryptedMimeTypes
|
||||
|
||||
def optional_chain(root, *keys):
|
||||
result = root
|
||||
@@ -267,7 +267,7 @@ class DetectPlugin(scrypted_sdk.ScryptedDeviceBase, ObjectDetection):
|
||||
print('detection starting', detection_id)
|
||||
b = await scrypted_sdk.mediaManager.convertMediaObjectToBuffer(mediaObject, ScryptedMimeTypes.MediaStreamUrl.value)
|
||||
s = b.decode('utf8')
|
||||
j: FFMpegInput = json.loads(s)
|
||||
j: FFmpegInput = json.loads(s)
|
||||
container = j.get('container', None)
|
||||
videosrc = j['url']
|
||||
if videosrc.startswith('tcp://'):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ScryptedDeviceType, ScryptedInterface, MediaObject, VideoCamera, Settings, Setting, Camera, ObjectDetection, PictureOptions, ScryptedDeviceBase, DeviceProvider, ScryptedMimeTypes, FFMpegInput, ObjectsDetected, ObjectDetectionModel, ObjectDetectionSession, ObjectDetectionResult } from '@scrypted/sdk';
|
||||
import { ScryptedDeviceType, ScryptedInterface, MediaObject, VideoCamera, Settings, Setting, Camera, ObjectDetection, PictureOptions, ScryptedDeviceBase, DeviceProvider, ScryptedMimeTypes, FFmpegInput, ObjectsDetected, ObjectDetectionModel, ObjectDetectionSession, ObjectDetectionResult } from '@scrypted/sdk';
|
||||
import sdk from '@scrypted/sdk';
|
||||
import * as tf from '@tensorflow/tfjs-node-gpu';
|
||||
import { ENV, tensor3d, Tensor3D } from '@tensorflow/tfjs-node-gpu';
|
||||
@@ -11,7 +11,7 @@ import { Canvas, Image, ImageData } from 'canvas';
|
||||
import { randomBytes } from 'crypto';
|
||||
import { sleep } from './sleep';
|
||||
import { makeBoundingBoxFromFace } from './util';
|
||||
import { FFMpegRebroadcastSession, startRebroadcastSession } from '../../../common/src/ffmpeg-rebroadcast';
|
||||
import { FFmpegRebroadcastSession, startRebroadcastSession } from '../../../common/src/ffmpeg-rebroadcast';
|
||||
import { createRawVideoParser, PIXEL_FORMAT_RGB24, StreamChunk } from '@scrypted/common/src/stream-parser';
|
||||
import { alertRecommendedPlugins } from '@scrypted/common/src/alert-recommended-plugins';
|
||||
import { once } from 'events';
|
||||
@@ -145,7 +145,7 @@ interface DetectionSession {
|
||||
events: EventEmitter;
|
||||
running?: boolean;
|
||||
|
||||
rebroadcaster?: Promise<FFMpegRebroadcastSession<RebroadcastParsers>>;
|
||||
rebroadcaster?: Promise<FFmpegRebroadcastSession<RebroadcastParsers>>;
|
||||
rebroadcasterTimeout?: NodeJS.Timeout;
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ class TensorFlow extends ScryptedDeviceBase implements ObjectDetection, DevicePr
|
||||
return;
|
||||
}
|
||||
|
||||
const ffmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(mediaObject, ScryptedMimeTypes.FFmpegInput)).toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse((await mediaManager.convertMediaObjectToBuffer(mediaObject, ScryptedMimeTypes.FFmpegInput)).toString()) as FFmpegInput;
|
||||
const rebroadcaster = startRebroadcastSession<RebroadcastParsers>(ffmpegInput, {
|
||||
console: this.console,
|
||||
parsers: {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, VideoCamera, MediaObject, MotionSensor, ScryptedInterface, Camera, MediaStreamOptions, Intercom, ScryptedMimeTypes, FFMpegInput, ObjectDetector, PictureOptions, ObjectDetectionTypes, ObjectsDetected, Notifier, VideoCameraConfiguration, OnOff, MediaStreamUrl, ResponseMediaStreamOptions } from "@scrypted/sdk";
|
||||
import sdk, { ScryptedDeviceBase, DeviceProvider, Settings, Setting, VideoCamera, MediaObject, MotionSensor, ScryptedInterface, Camera, MediaStreamOptions, Intercom, ScryptedMimeTypes, FFmpegInput, ObjectDetector, PictureOptions, ObjectDetectionTypes, ObjectsDetected, Notifier, VideoCameraConfiguration, OnOff, MediaStreamUrl, ResponseMediaStreamOptions } from "@scrypted/sdk";
|
||||
import { ProtectCameraChannelConfig, ProtectCameraConfigInterface, ProtectCameraLcdMessagePayload } from "./unifi-protect";
|
||||
import child_process, { ChildProcess } from 'child_process';
|
||||
import { ffmpegLogInitialOutput, safeKillFFmpeg } from '@scrypted/common/src/media-helpers';
|
||||
@@ -94,7 +94,7 @@ export class UnifiCamera extends ScryptedDeviceBase implements Notifier, Interco
|
||||
this.stopIntercom();
|
||||
|
||||
const buffer = await mediaManager.convertMediaObjectToBuffer(media, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = JSON.parse(buffer.toString()) as FFMpegInput;
|
||||
const ffmpegInput = JSON.parse(buffer.toString()) as FFmpegInput;
|
||||
|
||||
const camera = this.findCamera();
|
||||
const params = new URLSearchParams({ camera: camera.id });
|
||||
|
||||
@@ -5,7 +5,7 @@ import { connectRTCSignalingClients } from "@scrypted/common/src/rtc-connect";
|
||||
import { RtspServer } from "@scrypted/common/src/rtsp-server";
|
||||
import { createSdpInput, findFmtp } from "@scrypted/common/src/sdp-utils";
|
||||
import { StorageSettings } from "@scrypted/common/src/settings";
|
||||
import sdk, { FFMpegInput, Intercom, MediaStreamDestination, RTCAVSignalingSetup, RTCSignalingSession } from "@scrypted/sdk";
|
||||
import sdk, { FFmpegInput, Intercom, MediaStreamDestination, RTCAVSignalingSetup, RTCSignalingSession } from "@scrypted/sdk";
|
||||
import { ChildProcess } from "child_process";
|
||||
import ip from 'ip';
|
||||
import { WeriftOutputSignalingSession } from "./output-signaling-session";
|
||||
@@ -45,7 +45,7 @@ export async function createRTCPeerConnectionSink(
|
||||
storageSettings: StorageSettings<WebRTCStorageSettingsKeys>,
|
||||
console: Console,
|
||||
intercom: Intercom,
|
||||
getFFMpegInput: (destination: MediaStreamDestination) => Promise<FFMpegInput>,
|
||||
getFFmpegInput: (destination: MediaStreamDestination) => Promise<FFmpegInput>,
|
||||
) {
|
||||
|
||||
const options = await clientSignalingSession.getOptions();
|
||||
@@ -136,7 +136,7 @@ export async function createRTCPeerConnectionSink(
|
||||
audioTransceiver.onTrack.subscribe(async (track) => {
|
||||
try {
|
||||
const url = rtspTcpServer.url.replace('tcp:', 'rtsp:');
|
||||
const ffmpegInput: FFMpegInput = {
|
||||
const ffmpegInput: FFmpegInput = {
|
||||
url,
|
||||
inputArguments: [
|
||||
'-rtsp_transport', 'udp',
|
||||
@@ -209,7 +209,7 @@ export async function createRTCPeerConnectionSink(
|
||||
if (options?.userAgent?.includes('Firefox/'))
|
||||
sessionSupportsH264High = true;
|
||||
|
||||
const ffInput = await getFFMpegInput(isPrivate ? 'local' : 'remote');
|
||||
const ffInput = await getFFmpegInput(isPrivate ? 'local' : 'remote');
|
||||
const { mediaStreamOptions } = ffInput;
|
||||
|
||||
const videoArgs: string[] = [];
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AutoenableMixinProvider } from '@scrypted/common/src/autoenable-mixin-provider';
|
||||
import { SettingsMixinDeviceBase, SettingsMixinDeviceOptions } from '@scrypted/common/src/settings-mixin';
|
||||
import sdk, { BufferConverter, BufferConvertorOptions, DeviceCreator, DeviceCreatorSettings, DeviceProvider, FFMpegInput, Intercom, MediaObject, MixinProvider, RequestMediaStreamOptions, ResponseMediaStreamOptions, RTCSessionControl, RTCSignalingChannel, RTCSignalingSession, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk';
|
||||
import sdk, { BufferConverter, BufferConvertorOptions, DeviceCreator, DeviceCreatorSettings, DeviceProvider, FFmpegInput, Intercom, MediaObject, MixinProvider, RequestMediaStreamOptions, ResponseMediaStreamOptions, RTCSessionControl, RTCSignalingChannel, RTCSignalingSession, ScryptedDeviceType, ScryptedInterface, ScryptedMimeTypes, Setting, Settings, SettingValue, VideoCamera } from '@scrypted/sdk';
|
||||
import crypto from 'crypto';
|
||||
import { createRTCPeerConnectionSink } from "./ffmpeg-to-wrtc";
|
||||
import { WebRTCCamera } from "./webrtc-camera";
|
||||
@@ -72,7 +72,7 @@ class WebRTCMixin extends SettingsMixinDeviceBase<VideoCamera & RTCSignalingChan
|
||||
},
|
||||
destination,
|
||||
});
|
||||
const ffInput = await mediaManager.convertMediaObjectToJSON<FFMpegInput>(mo, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffInput = await mediaManager.convertMediaObjectToJSON<FFmpegInput>(mo, ScryptedMimeTypes.FFmpegInput);
|
||||
return ffInput;
|
||||
},
|
||||
);
|
||||
@@ -138,7 +138,7 @@ class WebRTCPlugin extends AutoenableMixinProvider implements DeviceCreator, Dev
|
||||
}
|
||||
|
||||
async convert(data: Buffer, fromMimeType: string, toMimeType: string, options?: BufferConvertorOptions): Promise<RTCSignalingChannel> {
|
||||
const ffmpegInput: FFMpegInput = JSON.parse(data.toString());
|
||||
const ffmpegInput: FFmpegInput = JSON.parse(data.toString());
|
||||
|
||||
const storageSettings = this.storageSettings;
|
||||
const console = deviceManager.getMixinConsole(options.sourceId, this.nativeId);
|
||||
|
||||
@@ -4,7 +4,7 @@ import { listenZeroSingleClient } from "@scrypted/common/src/listen-cluster";
|
||||
import { safeKillFFmpeg } from "@scrypted/common/src/media-helpers";
|
||||
import { RtspServer } from "@scrypted/common/src/rtsp-server";
|
||||
import { createSdpInput } from '@scrypted/common/src/sdp-utils';
|
||||
import sdk, { FFMpegInput, Intercom, MediaObject, ResponseMediaStreamOptions, RTCAVSignalingSetup, RTCSessionControl, RTCSignalingChannel, RTCSignalingOptions, RTCSignalingSendIceCandidate, RTCSignalingSession, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import sdk, { FFmpegInput, Intercom, MediaObject, ResponseMediaStreamOptions, RTCAVSignalingSetup, RTCSessionControl, RTCSignalingChannel, RTCSignalingOptions, RTCSignalingSendIceCandidate, RTCSignalingSession, ScryptedMimeTypes } from "@scrypted/sdk";
|
||||
import { ChildProcess } from "child_process";
|
||||
import dgram from 'dgram';
|
||||
import { Socket } from "net";
|
||||
@@ -15,7 +15,7 @@ import { createRawResponse, isPeerConnectionAlive } from "./werift-util";
|
||||
const { mediaManager } = sdk;
|
||||
|
||||
export interface RTCPeerConnectionPipe {
|
||||
ffmpegInput: FFMpegInput;
|
||||
ffmpegInput: FFmpegInput;
|
||||
intercom: Promise<Intercom>;
|
||||
}
|
||||
|
||||
@@ -326,7 +326,7 @@ export async function createRTCPeerConnectionSource(options: {
|
||||
if (!track)
|
||||
throw new Error('peer connection does not support two way audio');
|
||||
|
||||
const ffmpegInput = await mediaManager.convertMediaObjectToJSON<FFMpegInput>(media, ScryptedMimeTypes.FFmpegInput);
|
||||
const ffmpegInput = await mediaManager.convertMediaObjectToJSON<FFmpegInput>(media, ScryptedMimeTypes.FFmpegInput);
|
||||
|
||||
const { cp } = await startRtpForwarderProcess(console, ffmpegInput.inputArguments, {
|
||||
audio: {
|
||||
@@ -348,7 +348,7 @@ export async function createRTCPeerConnectionSource(options: {
|
||||
return ret;
|
||||
});
|
||||
|
||||
let ffmpegInput: FFMpegInput;
|
||||
let ffmpegInput: FFmpegInput;
|
||||
if (useUdp) {
|
||||
const url = `tcp://127.0.0.1:${port}`;
|
||||
|
||||
|
||||
@@ -958,9 +958,9 @@ export interface MediaManager {
|
||||
convertMediaObjectToUrl(mediaObject: string | MediaObject, toMimeType: string): Promise<string>;
|
||||
|
||||
/**
|
||||
* Create a MediaObject from FFMpeg input arguments.
|
||||
* Create a MediaObject from FFmpeg input arguments.
|
||||
*/
|
||||
createFFmpegMediaObject(ffmpegInput: FFMpegInput, options?: MediaObjectOptions): Promise<MediaObject>;
|
||||
createFFmpegMediaObject(ffmpegInput: FFmpegInput, options?: MediaObjectOptions): Promise<MediaObject>;
|
||||
|
||||
/**
|
||||
* Create a MediaObject from an URL. The mime type will be determined dynamically while resolving the url.
|
||||
@@ -989,7 +989,7 @@ export interface MediaStreamUrl {
|
||||
container?: string;
|
||||
mediaStreamOptions?: ResponseMediaStreamOptions;
|
||||
}
|
||||
export interface FFMpegInput extends MediaStreamUrl {
|
||||
export interface FFmpegInput extends MediaStreamUrl {
|
||||
inputArguments?: string[];
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -256,7 +256,7 @@ class EventListenerOptions(TypedDict):
|
||||
class EventListenerRegister(TypedDict):
|
||||
pass
|
||||
|
||||
class FFMpegInput(TypedDict):
|
||||
class FFmpegInput(TypedDict):
|
||||
container: str
|
||||
inputArguments: list[str]
|
||||
mediaStreamOptions: ResponseMediaStreamOptions
|
||||
@@ -986,7 +986,7 @@ class MediaManager:
|
||||
pass
|
||||
async def convertMediaObjectToUrl(self, mediaObject: str | MediaObject, toMimeType: str) -> str:
|
||||
pass
|
||||
async def createFFmpegMediaObject(self, ffmpegInput: FFMpegInput, options: MediaObjectOptions = None) -> MediaObject:
|
||||
async def createFFmpegMediaObject(self, ffmpegInput: FFmpegInput, options: MediaObjectOptions = None) -> MediaObject:
|
||||
pass
|
||||
async def createMediaObject(self, data: Any, mimeType: str, options: MediaObjectOptions = None) -> MediaObject:
|
||||
pass
|
||||
|
||||
6
sdk/types/index.d.ts
vendored
6
sdk/types/index.d.ts
vendored
@@ -1032,9 +1032,9 @@ export interface MediaManager {
|
||||
*/
|
||||
convertMediaObjectToUrl(mediaObject: string | MediaObject, toMimeType: string): Promise<string>;
|
||||
/**
|
||||
* Create a MediaObject from FFMpeg input arguments.
|
||||
* Create a MediaObject from FFmpeg input arguments.
|
||||
*/
|
||||
createFFmpegMediaObject(ffmpegInput: FFMpegInput, options?: MediaObjectOptions): Promise<MediaObject>;
|
||||
createFFmpegMediaObject(ffmpegInput: FFmpegInput, options?: MediaObjectOptions): Promise<MediaObject>;
|
||||
/**
|
||||
* Create a MediaObject from an URL. The mime type will be determined dynamically while resolving the url.
|
||||
*/
|
||||
@@ -1059,7 +1059,7 @@ export interface MediaStreamUrl {
|
||||
container?: string;
|
||||
mediaStreamOptions?: ResponseMediaStreamOptions;
|
||||
}
|
||||
export interface FFMpegInput extends MediaStreamUrl {
|
||||
export interface FFmpegInput extends MediaStreamUrl {
|
||||
inputArguments?: string[];
|
||||
}
|
||||
/**
|
||||
|
||||
@@ -1659,9 +1659,9 @@ export interface MediaManager {
|
||||
convertMediaObjectToUrl(mediaObject: string | MediaObject, toMimeType: string): Promise<string>;
|
||||
|
||||
/**
|
||||
* Create a MediaObject from FFMpeg input arguments.
|
||||
* Create a MediaObject from FFmpeg input arguments.
|
||||
*/
|
||||
createFFmpegMediaObject(ffmpegInput: FFMpegInput, options?: MediaObjectOptions): Promise<MediaObject>;
|
||||
createFFmpegMediaObject(ffmpegInput: FFmpegInput, options?: MediaObjectOptions): Promise<MediaObject>;
|
||||
|
||||
/**
|
||||
* Create a MediaObject from an URL. The mime type will be determined dynamically while resolving the url.
|
||||
@@ -1690,7 +1690,7 @@ export interface MediaStreamUrl {
|
||||
container?: string;
|
||||
mediaStreamOptions?: ResponseMediaStreamOptions;
|
||||
}
|
||||
export interface FFMpegInput extends MediaStreamUrl {
|
||||
export interface FFmpegInput extends MediaStreamUrl {
|
||||
inputArguments?: string[];
|
||||
}
|
||||
/**
|
||||
|
||||
4
sdk/types/package-lock.json
generated
4
sdk/types/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@scrypted/types",
|
||||
"version": "0.0.33",
|
||||
"version": "0.0.34",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@scrypted/types",
|
||||
"version": "0.0.33",
|
||||
"version": "0.0.34",
|
||||
"license": "ISC",
|
||||
"devDependencies": {}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@scrypted/types",
|
||||
"version": "0.0.33",
|
||||
"version": "0.0.34",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"author": "",
|
||||
|
||||
@@ -256,7 +256,7 @@ class EventListenerOptions(TypedDict):
|
||||
class EventListenerRegister(TypedDict):
|
||||
pass
|
||||
|
||||
class FFMpegInput(TypedDict):
|
||||
class FFmpegInput(TypedDict):
|
||||
container: str
|
||||
inputArguments: list[str]
|
||||
mediaStreamOptions: ResponseMediaStreamOptions
|
||||
@@ -986,7 +986,7 @@ class MediaManager:
|
||||
pass
|
||||
async def convertMediaObjectToUrl(self, mediaObject: str | MediaObject, toMimeType: str) -> str:
|
||||
pass
|
||||
async def createFFmpegMediaObject(self, ffmpegInput: FFMpegInput, options: MediaObjectOptions = None) -> MediaObject:
|
||||
async def createFFmpegMediaObject(self, ffmpegInput: FFmpegInput, options: MediaObjectOptions = None) -> MediaObject:
|
||||
pass
|
||||
async def createMediaObject(self, data: Any, mimeType: str, options: MediaObjectOptions = None) -> MediaObject:
|
||||
pass
|
||||
|
||||
14
server/package-lock.json
generated
14
server/package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.8",
|
||||
"@scrypted/ffmpeg": "^1.0.10",
|
||||
"@scrypted/types": "^0.0.33",
|
||||
"@scrypted/types": "^0.0.34",
|
||||
"adm-zip": "^0.5.3",
|
||||
"axios": "^0.21.1",
|
||||
"body-parser": "^1.19.0",
|
||||
@@ -157,9 +157,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@scrypted/types": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.0.33.tgz",
|
||||
"integrity": "sha512-1JYIh8jCv36XU8/0Hp5jRABpubFcfjhSZi4ZFKy4abEYtRwA6JWdtr6cIiW0s5A6WRacvqZ9aUjywWx1HhosEQ=="
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.0.34.tgz",
|
||||
"integrity": "sha512-hvjiGxlDGKun2+o3AtNVyoZVwgxD72TQi4/UVIkqbw4RN8HdEyedNUDDpKbDC6ZXLXxjvnGJYutOSc0qVrM/ow=="
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
"version": "1.1.2",
|
||||
@@ -3340,9 +3340,9 @@
|
||||
}
|
||||
},
|
||||
"@scrypted/types": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.0.33.tgz",
|
||||
"integrity": "sha512-1JYIh8jCv36XU8/0Hp5jRABpubFcfjhSZi4ZFKy4abEYtRwA6JWdtr6cIiW0s5A6WRacvqZ9aUjywWx1HhosEQ=="
|
||||
"version": "0.0.34",
|
||||
"resolved": "https://registry.npmjs.org/@scrypted/types/-/types-0.0.34.tgz",
|
||||
"integrity": "sha512-hvjiGxlDGKun2+o3AtNVyoZVwgxD72TQi4/UVIkqbw4RN8HdEyedNUDDpKbDC6ZXLXxjvnGJYutOSc0qVrM/ow=="
|
||||
},
|
||||
"@tootallnate/once": {
|
||||
"version": "1.1.2",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"dependencies": {
|
||||
"@mapbox/node-pre-gyp": "^1.0.8",
|
||||
"@scrypted/ffmpeg": "^1.0.10",
|
||||
"@scrypted/types": "^0.0.33",
|
||||
"@scrypted/types": "^0.0.34",
|
||||
"adm-zip": "^0.5.3",
|
||||
"axios": "^0.21.1",
|
||||
"body-parser": "^1.19.0",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { getInstalledFfmpeg } from '@scrypted/ffmpeg';
|
||||
import { BufferConverter, BufferConvertorOptions, DeviceManager, FFMpegInput, MediaManager, MediaObject, MediaObjectOptions, MediaStreamUrl, ScryptedInterface, ScryptedInterfaceProperty, ScryptedMimeTypes, ScryptedNativeId, SystemDeviceState, SystemManager } from "@scrypted/types";
|
||||
import { BufferConverter, BufferConvertorOptions, DeviceManager, FFmpegInput, MediaManager, MediaObject, MediaObjectOptions, MediaStreamUrl, ScryptedInterface, ScryptedInterfaceProperty, ScryptedMimeTypes, ScryptedNativeId, SystemDeviceState, SystemManager } from "@scrypted/types";
|
||||
import axios from 'axios';
|
||||
import child_process from 'child_process';
|
||||
import { once } from 'events';
|
||||
@@ -67,7 +67,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
||||
toMimeType: ScryptedMimeTypes.FFmpegInput,
|
||||
async convert(data, fromMimeType): Promise<Buffer> {
|
||||
const url = data.toString();
|
||||
const args: FFMpegInput = {
|
||||
const args: FFmpegInput = {
|
||||
url,
|
||||
inputArguments: [
|
||||
'-i', url,
|
||||
@@ -102,7 +102,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
||||
);
|
||||
}
|
||||
|
||||
const ret: FFMpegInput = Object.assign({
|
||||
const ret: FFmpegInput = Object.assign({
|
||||
inputArguments,
|
||||
}, mediaUrl);
|
||||
|
||||
@@ -124,7 +124,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
||||
convert: async (data, fromMimeType: string, toMimeType: string, options?: BufferConvertorOptions): Promise<Buffer> => {
|
||||
const console = this.getMixinConsole(options.sourceId, undefined);
|
||||
|
||||
const ffInput: FFMpegInput = JSON.parse(data.toString());
|
||||
const ffInput: FFmpegInput = JSON.parse(data.toString());
|
||||
|
||||
const args = [
|
||||
'-hide_banner',
|
||||
@@ -269,7 +269,7 @@ export abstract class MediaManagerBase implements MediaManager {
|
||||
return new MediaObjectImpl();
|
||||
}
|
||||
|
||||
async createFFmpegMediaObject(ffMpegInput: FFMpegInput, options?: MediaObjectOptions): Promise<MediaObject> {
|
||||
async createFFmpegMediaObject(ffMpegInput: FFmpegInput, options?: MediaObjectOptions): Promise<MediaObject> {
|
||||
return this.createMediaObjectRemote(Buffer.from(JSON.stringify(ffMpegInput)), ScryptedMimeTypes.FFmpegInput, options);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user