forked from Simnation/Main
ed
This commit is contained in:
parent
eac8cbb0db
commit
75219990cf
6 changed files with 45 additions and 434 deletions
|
@ -9,8 +9,6 @@ local PlyInCarCam = false
|
||||||
local bcamstate = false
|
local bcamstate = false
|
||||||
local carCam = false
|
local carCam = false
|
||||||
local onRec = false
|
local onRec = false
|
||||||
local isRecording = false
|
|
||||||
local isDashcamRecording = false
|
|
||||||
|
|
||||||
-- for prop and ped
|
-- for prop and ped
|
||||||
local propNetID = nil
|
local propNetID = nil
|
||||||
|
@ -769,88 +767,22 @@ RegisterNetEvent('spy-bodycam:client:deleteDecoyPed',function(plyId)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNetEvent('spy-bodycam:client:startRec',function(webhook,serviceUsed)
|
RegisterNetEvent('spy-bodycam:client:startRec',function(webhook,serviceUsed)
|
||||||
if isRecording then
|
SendNUIMessage({
|
||||||
SendNUIMessage({action = "cancel_rec_force"})
|
action = "toggle_record",
|
||||||
isRecording = false
|
hook = webhook,
|
||||||
NotifyPlayer('Recording stopped!', 'success', 2500)
|
service = serviceUsed,
|
||||||
|
recTiming = Config.RecordTime,
|
||||||
if Config.ForceViewCam then
|
})
|
||||||
onRec = false
|
if Config.ForceViewCam then
|
||||||
SetFollowPedCamViewMode(1)
|
SetTimecycleModifier(Config.CameraEffect.bodycam)
|
||||||
SetTimecycleModifier('default')
|
SetTimecycleModifierStrength(0.5)
|
||||||
SetTimecycleModifierStrength(1.0)
|
CreateThread(function()
|
||||||
end
|
onRec = true
|
||||||
else
|
while onRec do
|
||||||
SendNUIMessage({
|
SetFollowPedCamViewMode(4)
|
||||||
action = "toggle_record",
|
Wait(0)
|
||||||
hook = webhook,
|
end
|
||||||
service = serviceUsed,
|
end)
|
||||||
recTiming = Config.RecordTime,
|
|
||||||
})
|
|
||||||
isRecording = true
|
|
||||||
NotifyPlayer('Recording started!', 'success', 2500)
|
|
||||||
|
|
||||||
if Config.ForceViewCam then
|
|
||||||
SetTimecycleModifier(Config.CameraEffect.bodycam)
|
|
||||||
SetTimecycleModifierStrength(0.5)
|
|
||||||
CreateThread(function()
|
|
||||||
onRec = true
|
|
||||||
while onRec do
|
|
||||||
SetFollowPedCamViewMode(4)
|
|
||||||
Wait(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
RegisterNetEvent('spy-bodycam:client:startDashcamRec', function(webhook, serviceUsed, netId)
|
|
||||||
if isDashcamRecording then
|
|
||||||
SendNUIMessage({action = "stop_dashcam_recording"})
|
|
||||||
isDashcamRecording = false
|
|
||||||
NotifyPlayer('Dashcam recording stopped!', 'success', 2500)
|
|
||||||
|
|
||||||
if Config.ForceViewCam then
|
|
||||||
onRec = false
|
|
||||||
SetFollowPedCamViewMode(1)
|
|
||||||
SetTimecycleModifier('default')
|
|
||||||
SetTimecycleModifierStrength(1.0)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local veh = NetworkGetEntityFromNetworkId(netId)
|
|
||||||
if not DoesEntityExist(veh) then
|
|
||||||
NotifyPlayer('Vehicle not found!', 'error', 2500)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Get vehicle info for recording overlay
|
|
||||||
local carPlate = GetVehicleNumberPlateText(veh)
|
|
||||||
local carName = GetVehDisplayName(GetEntityModel(veh))
|
|
||||||
|
|
||||||
-- Send message to NUI to start recording
|
|
||||||
SendNUIMessage({
|
|
||||||
action = "toggle_dashcam_record",
|
|
||||||
hook = webhook,
|
|
||||||
service = serviceUsed,
|
|
||||||
recTiming = Config.RecordTime,
|
|
||||||
vehicleId = netId,
|
|
||||||
vehiclePlate = carPlate,
|
|
||||||
vehicleName = carName
|
|
||||||
})
|
|
||||||
isDashcamRecording = true
|
|
||||||
NotifyPlayer('Dashcam recording started!', 'success', 2500)
|
|
||||||
|
|
||||||
if Config.ForceViewCam then
|
|
||||||
SetTimecycleModifier(Config.CameraEffect.dashcam)
|
|
||||||
SetTimecycleModifierStrength(0.5)
|
|
||||||
CreateThread(function()
|
|
||||||
onRec = true
|
|
||||||
while onRec do
|
|
||||||
SetFollowPedCamViewMode(4)
|
|
||||||
Wait(0)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -873,42 +805,6 @@ RegisterNetEvent('spy-bodycam:client:refreshRecords',function(records,isBoss)
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Register hotkeys for recording if enabled in config
|
|
||||||
Citizen.CreateThread(function()
|
|
||||||
if Config.EnableRecordingHotkeys then
|
|
||||||
-- Bodycam recording hotkey
|
|
||||||
RegisterKeyMapping('bodycamrecord', 'Start/Stop bodycam recording', 'keyboard', Config.RecordHotkey)
|
|
||||||
RegisterCommand('bodycamrecord', function()
|
|
||||||
if bcamstate then -- Only if bodycam is active
|
|
||||||
TriggerServerEvent('spy-bodycam:server:toggleRecording')
|
|
||||||
else
|
|
||||||
NotifyPlayer('Bodycam not activated!', 'error', 2500)
|
|
||||||
end
|
|
||||||
end, false)
|
|
||||||
|
|
||||||
-- Dashcam recording hotkey
|
|
||||||
RegisterKeyMapping('dashcamrecord', 'Start/Stop dashcam recording', 'keyboard', Config.DashcamHotkey)
|
|
||||||
RegisterCommand('dashcamrecord', function()
|
|
||||||
if IsPedInAnyVehicle(cache.ped, false) then
|
|
||||||
local veh = GetVehiclePedIsIn(cache.ped, false)
|
|
||||||
if isCarAuth(veh) then
|
|
||||||
local netId = NetworkGetNetworkIdFromEntity(veh)
|
|
||||||
if GlobalState.CarsOnBodycam[netId] then
|
|
||||||
TriggerServerEvent('spy-bodycam:server:toggleDashcamRecording', netId)
|
|
||||||
else
|
|
||||||
NotifyPlayer('Dashcam not activated in this vehicle!', 'error', 2500)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
NotifyPlayer('Vehicle not authorized for dashcam!', 'error', 2500)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
NotifyPlayer('You need to be in a vehicle to use dashcam!', 'error', 2500)
|
|
||||||
end
|
|
||||||
end, false)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
RegisterKeyMapping('bodycamexit', 'Exit bodycam spectate', 'keyboard', Config.ExitCamKey)
|
RegisterKeyMapping('bodycamexit', 'Exit bodycam spectate', 'keyboard', Config.ExitCamKey)
|
||||||
RegisterCommand('bodycamexit', function()
|
RegisterCommand('bodycamexit', function()
|
||||||
if PlyInCam or PlyInCarCam then
|
if PlyInCam or PlyInCarCam then
|
||||||
|
@ -931,7 +827,7 @@ RegisterNUICallback('videoLog', function(data, cb)
|
||||||
local videoUrl = data.vidurl
|
local videoUrl = data.vidurl
|
||||||
local pos = GetEntityCoords(cache.ped)
|
local pos = GetEntityCoords(cache.ped)
|
||||||
local s1, s2 = GetStreetNameAtCoord(pos.x, pos.y, pos.z)
|
local s1, s2 = GetStreetNameAtCoord(pos.x, pos.y, pos.z)
|
||||||
TriggerServerEvent('spy-bodycam:server:logVideoDetails', videoUrl, GetStreetNameFromHashKey(s1), data.isDashcam)
|
TriggerServerEvent('spy-bodycam:server:logVideoDetails', videoUrl,GetStreetNameFromHashKey(s1))
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -1145,7 +1041,6 @@ function PlayWatchAnim(ped,isNet)
|
||||||
Citizen.Wait(10)
|
Citizen.Wait(10)
|
||||||
end
|
end
|
||||||
local prop = CreateObject(tabletprop, x, y, z + 0.2, isNet, true, false)
|
local prop = CreateObject(tabletprop, x, y, z + 0.2, isNet, true, false)
|
||||||
AttachEntityToEntity(prop, ped, GetPedBoneIndex(ped, 28422), -0.05, 0.0, 0.0, 0.0, 0.0, 0.0,
|
|
||||||
AttachEntityToEntity(prop, ped, GetPedBoneIndex(ped, 28422), -0.05, 0.0, 0.0, 0.0, 0.0, 0.0, true, true, false, true, 1, true)
|
AttachEntityToEntity(prop, ped, GetPedBoneIndex(ped, 28422), -0.05, 0.0, 0.0, 0.0, 0.0, 0.0, true, true, false, true, 1, true)
|
||||||
local animDict = 'amb@code_human_in_bus_passenger_idles@female@tablet@idle_a'
|
local animDict = 'amb@code_human_in_bus_passenger_idles@female@tablet@idle_a'
|
||||||
RequestAnimDict(animDict)
|
RequestAnimDict(animDict)
|
||||||
|
@ -1325,37 +1220,4 @@ function HasItemsCheck(itemname)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Register hotkeys for recording
|
|
||||||
if Config.EnableRecordingHotkeys then
|
|
||||||
RegisterCommand('+bodycamrecord', function()
|
|
||||||
if bcamstate then
|
|
||||||
TriggerServerEvent('spy-bodycam:server:toggleRecording')
|
|
||||||
else
|
|
||||||
NotifyPlayer('Bodycam not activated!', 'error', 2500)
|
|
||||||
end
|
|
||||||
end, false)
|
|
||||||
|
|
||||||
RegisterCommand('+dashcamrecord', function()
|
|
||||||
if IsPedInAnyVehicle(cache.ped, false) then
|
|
||||||
local veh = GetVehiclePedIsIn(cache.ped, false)
|
|
||||||
if isCarAuth(veh) then
|
|
||||||
local netId = NetworkGetNetworkIdFromEntity(veh)
|
|
||||||
if GlobalState.CarsOnBodycam[netId] then
|
|
||||||
TriggerServerEvent('spy-bodycam:server:toggleDashcamRecording', netId)
|
|
||||||
else
|
|
||||||
NotifyPlayer('Dashcam not activated in this vehicle!', 'error', 2500)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
NotifyPlayer('Vehicle not authorized for dashcam!', 'error', 2500)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
NotifyPlayer('You need to be in a vehicle to use dashcam!', 'error', 2500)
|
|
||||||
end
|
|
||||||
end, false)
|
|
||||||
|
|
||||||
RegisterKeyMapping('+bodycamrecord', 'Start/Stop bodycam recording', 'keyboard', Config.RecordHotkey)
|
|
||||||
RegisterKeyMapping('+dashcamrecord', 'Start/Stop dashcam recording', 'keyboard', Config.DashcamHotkey)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,10 @@ Config.Dependency = {
|
||||||
UseProgress = 'qb', -- qb | ox | esx
|
UseProgress = 'qb', -- qb | ox | esx
|
||||||
UseMenu = 'qb', -- qb | ox | esx
|
UseMenu = 'qb', -- qb | ox | esx
|
||||||
UseNotify = 'qb', -- qb | ox | esx
|
UseNotify = 'qb', -- qb | ox | esx
|
||||||
UseAppearance = 'illenium', -- qb | illenium | false
|
UseAppearance = 'illenium', -- qb | illenium | false
|
||||||
}
|
}
|
||||||
|
|
||||||
Config.ExitCamKey = 'BACK'
|
Config.ExitCamKey = 'BACK'
|
||||||
Config.RecordHotkey = 'F1' -- Hotkey for bodycam recording
|
|
||||||
Config.DashcamHotkey = 'F10' -- Hotkey for dashcam recording
|
|
||||||
Config.EnableRecordingHotkeys = true -- Enable/disable hotkey functionality
|
|
||||||
|
|
||||||
Config.CameraEffect = {
|
Config.CameraEffect = {
|
||||||
bodycam = 'Island_CCTV_ChannelFuzz',
|
bodycam = 'Island_CCTV_ChannelFuzz',
|
||||||
|
@ -122,4 +119,4 @@ Config.VehCamOffset = {
|
||||||
-- 19: Military
|
-- 19: Military
|
||||||
-- 20: Commercial
|
-- 20: Commercial
|
||||||
-- 21: Trains
|
-- 21: Trains
|
||||||
-- 22: Open Wheel
|
-- 22: Open Wheel
|
|
@ -161,71 +161,13 @@ Citizen.CreateThread(function()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- Handle bodycam recording toggle
|
RegisterNetEvent('spy-bodycam:server:logVideoDetails', function(videoUrl,streetName)
|
||||||
RegisterNetEvent('spy-bodycam:server:toggleRecording', function()
|
|
||||||
local src = source
|
|
||||||
if PlayerOnBodycam[src] then
|
|
||||||
local defwebhook
|
|
||||||
if Upload.ServiceUsed == 'discord' then
|
|
||||||
local jobKey
|
|
||||||
if Config.Framework == 'qb' then
|
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
|
||||||
jobKey = Player.PlayerData.job.name
|
|
||||||
else
|
|
||||||
local xPlayer = ESX.GetPlayerFromId(src)
|
|
||||||
jobKey = xPlayer.getJob().name
|
|
||||||
end
|
|
||||||
if Upload.JobUploads[jobKey] then
|
|
||||||
defwebhook = Upload.JobUploads[jobKey].webhook
|
|
||||||
else
|
|
||||||
defwebhook = Upload.DefaultUploads.webhook
|
|
||||||
end
|
|
||||||
elseif Upload.ServiceUsed == 'fivemanage' or Upload.ServiceUsed == 'fivemerr' then
|
|
||||||
defwebhook = Upload.Token
|
|
||||||
end
|
|
||||||
TriggerClientEvent('spy-bodycam:client:startRec', src, defwebhook, Upload.ServiceUsed)
|
|
||||||
else
|
|
||||||
NotifyPlayerSv('Bodycam not turned on!', 'error', 3000, src)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Handle dashcam recording toggle
|
|
||||||
RegisterNetEvent('spy-bodycam:server:toggleDashcamRecording', function(netId)
|
|
||||||
local src = source
|
|
||||||
if CarsOnBodycam[netId] then
|
|
||||||
local defwebhook
|
|
||||||
if Upload.ServiceUsed == 'discord' then
|
|
||||||
local jobKey
|
|
||||||
if Config.Framework == 'qb' then
|
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
|
||||||
jobKey = Player.PlayerData.job.name
|
|
||||||
else
|
|
||||||
local xPlayer = ESX.GetPlayerFromId(src)
|
|
||||||
jobKey = xPlayer.getJob().name
|
|
||||||
end
|
|
||||||
if Upload.JobUploads[jobKey] then
|
|
||||||
defwebhook = Upload.JobUploads[jobKey].webhook
|
|
||||||
else
|
|
||||||
defwebhook = Upload.DefaultUploads.webhook
|
|
||||||
end
|
|
||||||
elseif Upload.ServiceUsed == 'fivemanage' or Upload.ServiceUsed == 'fivemerr' then
|
|
||||||
defwebhook = Upload.Token
|
|
||||||
end
|
|
||||||
TriggerClientEvent('spy-bodycam:client:startDashcamRec', src, defwebhook, Upload.ServiceUsed, netId)
|
|
||||||
else
|
|
||||||
NotifyPlayerSv('Dashcam not turned on!', 'error', 3000, src)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
RegisterNetEvent('spy-bodycam:server:logVideoDetails', function(videoUrl, streetName, isDashcam)
|
|
||||||
local src = source
|
local src = source
|
||||||
local offName
|
local offName
|
||||||
local offJob
|
local offJob
|
||||||
local offRank
|
local offRank
|
||||||
local jobKey
|
local jobKey
|
||||||
local date = os.date('%Y-%m-%d')
|
local date = os.date('%Y-%m-%d')
|
||||||
local recordType = isDashcam and "dashcam" or "bodycam"
|
|
||||||
|
|
||||||
if Config.Framework == 'qb' then
|
if Config.Framework == 'qb' then
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
local Player = QBCore.Functions.GetPlayer(src)
|
||||||
|
@ -242,13 +184,12 @@ RegisterNetEvent('spy-bodycam:server:logVideoDetails', function(videoUrl, street
|
||||||
end
|
end
|
||||||
|
|
||||||
---SQL UPLOAD
|
---SQL UPLOAD
|
||||||
MySQL.Async.execute('INSERT INTO spy_bodycam (job, videolink, street, date, playername, recordtype) VALUES (@job, @videolink, @street, @date, @playername, @recordtype)', {
|
MySQL.Async.execute('INSERT INTO spy_bodycam (job, videolink, street, date, playername) VALUES (@job, @videolink, @street, @date, @playername)', {
|
||||||
['@job'] = jobKey,
|
['@job'] = jobKey,
|
||||||
['@videolink'] = videoUrl,
|
['@videolink'] = videoUrl,
|
||||||
['@street'] = streetName,
|
['@street'] = streetName,
|
||||||
['@date'] = date,
|
['@date'] = date,
|
||||||
['@playername'] = offName,
|
['@playername'] = offName
|
||||||
['@recordtype'] = recordType
|
|
||||||
}, function(rowsChanged) end)
|
}, function(rowsChanged) end)
|
||||||
|
|
||||||
if Upload.DiscordLogs.Enabled then
|
if Upload.DiscordLogs.Enabled then
|
||||||
|
@ -263,7 +204,7 @@ RegisterNetEvent('spy-bodycam:server:logVideoDetails', function(videoUrl, street
|
||||||
end
|
end
|
||||||
local embedData = {
|
local embedData = {
|
||||||
{
|
{
|
||||||
title = Upload.DiscordLogs.Title .. (isDashcam and " (Dashcam)" or " (Bodycam)"),
|
title = Upload.DiscordLogs.Title,
|
||||||
color = 16761035,
|
color = 16761035,
|
||||||
fields = {
|
fields = {
|
||||||
{ name = "Name:", value = offName, inline = false },
|
{ name = "Name:", value = offName, inline = false },
|
||||||
|
@ -271,7 +212,7 @@ RegisterNetEvent('spy-bodycam:server:logVideoDetails', function(videoUrl, street
|
||||||
{ name = "Job Rank:", value = offRank, inline = false },
|
{ name = "Job Rank:", value = offRank, inline = false },
|
||||||
},
|
},
|
||||||
footer = {
|
footer = {
|
||||||
text = "Date: " .. os.date("!%Y-%m-%d %H:%M:%S", os.time()),
|
text = "Date: " .. os.date("!%Y-%m-%d %H:%M:%S", os.time()),
|
||||||
icon_url = "https://i.imgur.com/CuSyeZT.png",
|
icon_url = "https://i.imgur.com/CuSyeZT.png",
|
||||||
},
|
},
|
||||||
author = author
|
author = author
|
||||||
|
@ -429,58 +370,4 @@ AddEventHandler('onResourceStart', function(resourceName)
|
||||||
checkForUpdates()
|
checkForUpdates()
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
-- Handle bodycam recording toggle
|
|
||||||
RegisterNetEvent('spy-bodycam:server:toggleRecording', function()
|
|
||||||
local src = source
|
|
||||||
if PlayerOnBodycam[src] then
|
|
||||||
local defwebhook
|
|
||||||
if Upload.ServiceUsed == 'discord' then
|
|
||||||
local jobKey
|
|
||||||
if Config.Framework == 'qb' then
|
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
|
||||||
jobKey = Player.PlayerData.job.name
|
|
||||||
else
|
|
||||||
local xPlayer = ESX.GetPlayerFromId(src)
|
|
||||||
jobKey = xPlayer.getJob().name
|
|
||||||
end
|
|
||||||
if Upload.JobUploads[jobKey] then
|
|
||||||
defwebhook = Upload.JobUploads[jobKey].webhook
|
|
||||||
else
|
|
||||||
defwebhook = Upload.DefaultUploads.webhook
|
|
||||||
end
|
|
||||||
elseif Upload.ServiceUsed == 'fivemanage' or Upload.ServiceUsed == 'fivemerr' then
|
|
||||||
defwebhook = Upload.Token
|
|
||||||
end
|
|
||||||
TriggerClientEvent('spy-bodycam:client:startRec', src, defwebhook, Upload.ServiceUsed)
|
|
||||||
else
|
|
||||||
NotifyPlayerSv('Bodycam not turned on!', 'error', 3000, src)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- Handle dashcam recording toggle
|
|
||||||
RegisterNetEvent('spy-bodycam:server:toggleDashcamRecording', function(netId)
|
|
||||||
local src = source
|
|
||||||
if CarsOnBodycam[netId] then
|
|
||||||
local defwebhook
|
|
||||||
if Upload.ServiceUsed == 'discord' then
|
|
||||||
local jobKey
|
|
||||||
if Config.Framework == 'qb' then
|
|
||||||
local Player = QBCore.Functions.GetPlayer(src)
|
|
||||||
jobKey = Player.PlayerData.job.name
|
|
||||||
else
|
|
||||||
local xPlayer = ESX.GetPlayerFromId(src)
|
|
||||||
jobKey = xPlayer.getJob().name
|
|
||||||
end
|
|
||||||
if Upload.JobUploads[jobKey] then
|
|
||||||
defwebhook = Upload.JobUploads[jobKey].webhook
|
|
||||||
else
|
|
||||||
defwebhook = Upload.DefaultUploads.webhook
|
|
||||||
end
|
|
||||||
elseif Upload.ServiceUsed == 'fivemanage' or Upload.ServiceUsed == 'fivemerr' then
|
|
||||||
defwebhook = Upload.Token
|
|
||||||
end
|
|
||||||
TriggerClientEvent('spy-bodycam:client:startDashcamRec', src, defwebhook, Upload.ServiceUsed, netId)
|
|
||||||
else
|
|
||||||
NotifyPlayerSv('Dashcam not turned on!', 'error', 3000, src)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
|
@ -79,18 +79,9 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Dashcam Recording UI -->
|
|
||||||
<div id="dashcam-recording-ui">
|
|
||||||
<div class="dashcam-header">
|
|
||||||
<div class="dashcam-recording-indicator"></div>
|
|
||||||
<span>DASHCAM RECORDING</span>
|
|
||||||
</div>
|
|
||||||
<div id="dashcam-vehicle-info">Police Cruiser - ABC123</div>
|
|
||||||
<div id="dashcam-timer">00:00</div>
|
|
||||||
</div>
|
|
||||||
<audio id="beep-sound" src="audio/on_sound.mp3"></audio>
|
<audio id="beep-sound" src="audio/on_sound.mp3"></audio>
|
||||||
<audio id="off-sound" src="audio/off_sound.mp3"></audio>
|
<audio id="off-sound" src="audio/off_sound.mp3"></audio>
|
||||||
<script src="js/jquery-3.7.1.min.js"></script>
|
<script src="js/jquery-3.7.1.min.js"></script>
|
||||||
<script type="module" src="js/app.js"></script>
|
<script type="module" src="js/app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,10 +1,7 @@
|
||||||
import { GameView } from './gameview.js';
|
import { GameView } from './gameview.js';
|
||||||
const gameview = new GameView();
|
const gameview = new GameView();
|
||||||
let isRecording = false;
|
let isRecording = false;
|
||||||
let isDashcamRecording = false;
|
|
||||||
let recordingTimeout;
|
let recordingTimeout;
|
||||||
let dashcamRecordingTimeout;
|
|
||||||
let dashcamTimer;
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
$('.overlayCont').hide();
|
$('.overlayCont').hide();
|
||||||
|
@ -13,7 +10,6 @@ $(document).ready(function () {
|
||||||
$('.recCont').hide();
|
$('.recCont').hide();
|
||||||
$('.askMain').hide();
|
$('.askMain').hide();
|
||||||
$('.vidplaycont').hide();
|
$('.vidplaycont').hide();
|
||||||
$('#dashcam-recording-ui').hide();
|
|
||||||
const beepSound = document.getElementById('beep-sound');
|
const beepSound = document.getElementById('beep-sound');
|
||||||
const offSound = document.getElementById('off-sound');
|
const offSound = document.getElementById('off-sound');
|
||||||
|
|
||||||
|
@ -102,7 +98,7 @@ $(document).ready(function () {
|
||||||
startRecording(data.hook, data.service);
|
startRecording(data.hook, data.service);
|
||||||
recordingTimeout = setTimeout(() => {
|
recordingTimeout = setTimeout(() => {
|
||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
// Stop recording automatically after configured time
|
// Stop recording automatically after 30 seconds
|
||||||
isRecording = false;
|
isRecording = false;
|
||||||
$('.HeadText').html('<i class="fa-solid fa-circle bodyIcon" style="color: white;"></i>' + 'Recording Stopped');
|
$('.HeadText').html('<i class="fa-solid fa-circle bodyIcon" style="color: white;"></i>' + 'Recording Stopped');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
@ -122,53 +118,6 @@ $(document).ready(function () {
|
||||||
stopRecording();
|
stopRecording();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (data.action === 'toggle_dashcam_record') {
|
|
||||||
clearTimeout(dashcamRecordingTimeout);
|
|
||||||
if (!isDashcamRecording) {
|
|
||||||
// Start dashcam recording
|
|
||||||
isDashcamRecording = true;
|
|
||||||
$('#dashcam-recording-ui').show();
|
|
||||||
$('#dashcam-vehicle-info').text(`${data.vehicleName} - ${data.vehiclePlate}`);
|
|
||||||
|
|
||||||
// Start a timer for the dashcam recording
|
|
||||||
let seconds = 0;
|
|
||||||
dashcamTimer = setInterval(() => {
|
|
||||||
seconds++;
|
|
||||||
const mins = Math.floor(seconds / 60);
|
|
||||||
const secs = seconds % 60;
|
|
||||||
$('#dashcam-timer').text(`${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`);
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
// Start recording using the existing function
|
|
||||||
startRecording(data.hook, data.service, data.recTiming, true);
|
|
||||||
|
|
||||||
// Auto-stop after the configured time
|
|
||||||
dashcamRecordingTimeout = setTimeout(() => {
|
|
||||||
if (isDashcamRecording) {
|
|
||||||
isDashcamRecording = false;
|
|
||||||
$('#dashcam-recording-ui').hide();
|
|
||||||
clearInterval(dashcamTimer);
|
|
||||||
stopRecording(true);
|
|
||||||
}
|
|
||||||
}, data.recTiming * 1000);
|
|
||||||
} else {
|
|
||||||
// Stop dashcam recording
|
|
||||||
isDashcamRecording = false;
|
|
||||||
$('#dashcam-recording-ui').hide();
|
|
||||||
clearTimeout(dashcamRecordingTimeout);
|
|
||||||
clearInterval(dashcamTimer);
|
|
||||||
stopRecording(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.action === 'stop_dashcam_recording') {
|
|
||||||
if (isDashcamRecording) {
|
|
||||||
isDashcamRecording = false;
|
|
||||||
$('#dashcam-recording-ui').hide();
|
|
||||||
clearTimeout(dashcamRecordingTimeout);
|
|
||||||
clearInterval(dashcamTimer);
|
|
||||||
stopRecording(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (data.action === 'cancel_rec_force') {
|
if (data.action === 'cancel_rec_force') {
|
||||||
if (isRecording) {
|
if (isRecording) {
|
||||||
// Force stop recording
|
// Force stop recording
|
||||||
|
@ -180,13 +129,6 @@ $(document).ready(function () {
|
||||||
}, 1000);
|
}, 1000);
|
||||||
stopRecording();
|
stopRecording();
|
||||||
}
|
}
|
||||||
if (isDashcamRecording) {
|
|
||||||
isDashcamRecording = false;
|
|
||||||
$('#dashcam-recording-ui').hide();
|
|
||||||
clearTimeout(dashcamRecordingTimeout);
|
|
||||||
clearInterval(dashcamTimer);
|
|
||||||
stopRecording(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RECORDS SHOWING
|
// RECORDS SHOWING
|
||||||
|
@ -196,18 +138,16 @@ $(document).ready(function () {
|
||||||
|
|
||||||
if (Array.isArray(data.recordData) && data.recordData.length > 0) {
|
if (Array.isArray(data.recordData) && data.recordData.length > 0) {
|
||||||
$.each(data.recordData, function (index, record) {
|
$.each(data.recordData, function (index, record) {
|
||||||
var recordType = record.recordtype || 'bodycam';
|
|
||||||
var recordIcon = recordType === 'dashcam' ? 'fa-car' : 'fa-video';
|
|
||||||
var camBox = $(
|
var camBox = $(
|
||||||
`
|
`
|
||||||
<div class="camBox">
|
<div class="camBox">
|
||||||
<div class="camInfo">
|
<div class="camInfo">
|
||||||
<div class="camTitle">${record.playername}<span class="camStreet"> [${record.street}]</span></div>
|
<div class="camTitle">${record.playername}<span class="camStreet"> [${record.street}]</span></div>
|
||||||
<div class="camDesc">${recordType.toUpperCase()} | Date: ${record.date}</div>
|
<div class="camDesc">Date: ${record.date}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="camIcons">
|
<div class="camIcons">
|
||||||
<div class="camShow" data-stored="${record.videolink}"><i class="fa-solid fa-eye"></i></div>
|
<div class="camShow" data-stored="${record.videolink}"><i class="fa-solid fa-eye"></i></div>
|
||||||
${data.isBoss ? `<div class="camDelete" data-url="${record.videolink}"><i class="fa-solid fa-trash"></i></div>` : ''}
|
${data.isBoss ? `<div class="camDelete"><i class="fa-solid fa-trash"></i></div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
@ -226,18 +166,16 @@ $(document).ready(function () {
|
||||||
$('.recInnerScroll').empty();
|
$('.recInnerScroll').empty();
|
||||||
if (Array.isArray(data.recordData) && data.recordData.length > 0) {
|
if (Array.isArray(data.recordData) && data.recordData.length > 0) {
|
||||||
$.each(data.recordData, function (index, record) {
|
$.each(data.recordData, function (index, record) {
|
||||||
var recordType = record.recordtype || 'bodycam';
|
|
||||||
var recordIcon = recordType === 'dashcam' ? 'fa-car' : 'fa-video';
|
|
||||||
var camBox = $(
|
var camBox = $(
|
||||||
`
|
`
|
||||||
<div class="camBox">
|
<div class="camBox">
|
||||||
<div class="camInfo">
|
<div class="camInfo">
|
||||||
<div class="camTitle">${record.playername}<span class="camStreet"> [${record.street}]</span></div>
|
<div class="camTitle">${record.playername}<span class="camStreet"> [${record.street}]</span></div>
|
||||||
<div class="camDesc">${recordType.toUpperCase()} | Date: ${record.date}</div>
|
<div class="camDesc">Date: ${record.date}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="camIcons">
|
<div class="camIcons">
|
||||||
<div class="camShow" data-stored="${record.videolink}"><i class="fa-solid fa-eye"></i></div>
|
<div class="camShow" data-stored="${record.videolink}"><i class="fa-solid fa-eye"></i></div>
|
||||||
${data.isBoss ? `<div class="camDelete" data-url="${record.videolink}"><i class="fa-solid fa-trash"></i></div>` : ''}
|
${data.isBoss ? `<div class="camDelete"><i class="fa-solid fa-trash"></i></div>` : ''}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
@ -258,7 +196,7 @@ $(document).ready(function () {
|
||||||
function updateVisibility(searchText) {
|
function updateVisibility(searchText) {
|
||||||
$('.camBox').each(function () {
|
$('.camBox').each(function () {
|
||||||
var camTitleText = $(this).find('.camTitle').text().toLowerCase();
|
var camTitleText = $(this).find('.camTitle').text().toLowerCase();
|
||||||
var camDescDate = $(this).find('.camDesc').text().trim().replace(/.*Date: /, '');
|
var camDescDate = $(this).find('.camDesc').text().trim().replace('Date: ', '');
|
||||||
if ((searchText === '' || camTitleText.includes(searchText)) &&
|
if ((searchText === '' || camTitleText.includes(searchText)) &&
|
||||||
($(this).css('display') !== 'none' || camDescDate === $('.selectedDate').val())
|
($(this).css('display') !== 'none' || camDescDate === $('.selectedDate').val())
|
||||||
) {
|
) {
|
||||||
|
@ -282,7 +220,7 @@ $(document).ready(function () {
|
||||||
$('.selectedDate').on('change', function () {
|
$('.selectedDate').on('change', function () {
|
||||||
var selectedDate = $(this).val();
|
var selectedDate = $(this).val();
|
||||||
$('.camBox').each(function () {
|
$('.camBox').each(function () {
|
||||||
var camDescDate = $(this).find('.camDesc').text().trim().replace(/.*Date: /, '');
|
var camDescDate = $(this).find('.camDesc').text().trim().replace('Date: ', '');
|
||||||
if (selectedDate === '') {
|
if (selectedDate === '') {
|
||||||
$(this).show();
|
$(this).show();
|
||||||
} else if (selectedDate === camDescDate) {
|
} else if (selectedDate === camDescDate) {
|
||||||
|
@ -297,7 +235,7 @@ $(document).ready(function () {
|
||||||
|
|
||||||
$(document).on('click', '.camDelete', function () {
|
$(document).on('click', '.camDelete', function () {
|
||||||
const camBox = $(this).closest('.camBox');
|
const camBox = $(this).closest('.camBox');
|
||||||
deleteUrl = $(this).data('url');
|
deleteUrl = camBox.find('.camShow').data('stored');
|
||||||
$('.askMain').fadeIn();
|
$('.askMain').fadeIn();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -349,7 +287,7 @@ let mediaRecorder;
|
||||||
let audioStream;
|
let audioStream;
|
||||||
const canvasElement = document.querySelector('canvas');
|
const canvasElement = document.querySelector('canvas');
|
||||||
|
|
||||||
async function uploadBlob(videoBlob, hook, service, isDashcam = false) {
|
async function uploadBlob(videoBlob, hook, service) {
|
||||||
$.post(`https://${GetParentResourceName()}/exitBodyCam`, '{}');
|
$.post(`https://${GetParentResourceName()}/exitBodyCam`, '{}');
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
try {
|
try {
|
||||||
|
@ -368,8 +306,7 @@ async function uploadBlob(videoBlob, hook, service, isDashcam = false) {
|
||||||
}
|
}
|
||||||
responseData = await response.json();
|
responseData = await response.json();
|
||||||
$.post(`https://${GetParentResourceName()}/videoLog`, JSON.stringify({
|
$.post(`https://${GetParentResourceName()}/videoLog`, JSON.stringify({
|
||||||
vidurl: responseData.url,
|
vidurl: responseData.url
|
||||||
isDashcam: isDashcam
|
|
||||||
}));
|
}));
|
||||||
} else if (service === 'fivemerr') {
|
} else if (service === 'fivemerr') {
|
||||||
formData.append('file', videoBlob, 'video.webm');
|
formData.append('file', videoBlob, 'video.webm');
|
||||||
|
@ -385,8 +322,7 @@ async function uploadBlob(videoBlob, hook, service, isDashcam = false) {
|
||||||
}
|
}
|
||||||
responseData = await response.json();
|
responseData = await response.json();
|
||||||
$.post(`https://${GetParentResourceName()}/videoLog`, JSON.stringify({
|
$.post(`https://${GetParentResourceName()}/videoLog`, JSON.stringify({
|
||||||
vidurl: responseData.url,
|
vidurl: responseData.url
|
||||||
isDashcam: isDashcam
|
|
||||||
}));
|
}));
|
||||||
} else if (service === 'discord') {
|
} else if (service === 'discord') {
|
||||||
formData.append('file', videoBlob, 'video.webm');
|
formData.append('file', videoBlob, 'video.webm');
|
||||||
|
@ -399,8 +335,7 @@ async function uploadBlob(videoBlob, hook, service, isDashcam = false) {
|
||||||
}
|
}
|
||||||
responseData = await response.json();
|
responseData = await response.json();
|
||||||
$.post(`https://${GetParentResourceName()}/videoLog`, JSON.stringify({
|
$.post(`https://${GetParentResourceName()}/videoLog`, JSON.stringify({
|
||||||
vidurl: responseData.attachments[0].url,
|
vidurl: responseData.attachments[0].url
|
||||||
isDashcam: isDashcam
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -418,16 +353,15 @@ async function startMicrophoneCapture() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function startRecording(hook, service, recordTime, isDashcam = false) {
|
async function startRecording(hook, service) {
|
||||||
audioStream = await startMicrophoneCapture();
|
audioStream = await startMicrophoneCapture();
|
||||||
if (!isRecording && !isDashcamRecording) {
|
if (!isRecording){
|
||||||
if (audioStream) {
|
if (audioStream) {
|
||||||
audioStream.getAudioTracks().forEach(track => track.stop());
|
audioStream.getAudioTracks().forEach(track => track.stop());
|
||||||
}
|
}
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
|
console.log('Video Recording Started');
|
||||||
console.log(isDashcam ? 'Dashcam Recording Started' : 'Bodycam Recording Started');
|
|
||||||
const gameView = gameview.createGameView(canvasElement);
|
const gameView = gameview.createGameView(canvasElement);
|
||||||
const canvasStream = canvasElement.captureStream(30);
|
const canvasStream = canvasElement.captureStream(30);
|
||||||
|
|
||||||
|
@ -445,7 +379,7 @@ async function startRecording(hook, service, recordTime, isDashcam = false) {
|
||||||
mediaRecorder.onstop = async () => {
|
mediaRecorder.onstop = async () => {
|
||||||
const videoBlob = new Blob(videoChunks, { type: 'video/webm' });
|
const videoBlob = new Blob(videoChunks, { type: 'video/webm' });
|
||||||
if (videoBlob.size > 0) {
|
if (videoBlob.size > 0) {
|
||||||
uploadBlob(videoBlob, hook, service, isDashcam);
|
uploadBlob(videoBlob, hook, service);
|
||||||
}
|
}
|
||||||
if (audioStream) {
|
if (audioStream) {
|
||||||
audioStream.getAudioTracks().forEach(track => track.stop());
|
audioStream.getAudioTracks().forEach(track => track.stop());
|
||||||
|
@ -453,15 +387,8 @@ async function startRecording(hook, service, recordTime, isDashcam = false) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopRecording(isDashcam = false) {
|
function stopRecording() {
|
||||||
if (mediaRecorder && mediaRecorder.state === 'recording') {
|
if (mediaRecorder && mediaRecorder.state === 'recording') {
|
||||||
mediaRecorder.stop();
|
mediaRecorder.stop();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (isDashcam) {
|
|
||||||
isDashcamRecording = false;
|
|
||||||
$('#dashcam-recording-ui').hide();
|
|
||||||
} else {
|
|
||||||
isRecording = false;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -448,57 +448,4 @@
|
||||||
color: rgba(255, 255, 255, 0.26);
|
color: rgba(255, 255, 255, 0.26);
|
||||||
font-size: 3rem;
|
font-size: 3rem;
|
||||||
font-family: "Fjalla One", sans-serif;
|
font-family: "Fjalla One", sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dashcam Recording UI */
|
|
||||||
#dashcam-recording-ui {
|
|
||||||
position: absolute;
|
|
||||||
top: 20px;
|
|
||||||
left: 20px;
|
|
||||||
background-color: rgba(0, 0, 0, 0.7);
|
|
||||||
color: white;
|
|
||||||
padding: 15px;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-family: "Play", sans-serif;
|
|
||||||
display: none;
|
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
|
||||||
border: 1px solid rgba(255, 0, 0, 0.3);
|
|
||||||
min-width: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashcam-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#dashcam-vehicle-info {
|
|
||||||
font-size: 14px;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
color: #f0f0f0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#dashcam-timer {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #ff3333;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashcam-recording-indicator {
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
background-color: red;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: inline-block;
|
|
||||||
margin-right: 10px;
|
|
||||||
animation: blink 1s infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes blink {
|
|
||||||
0% { opacity: 1; }
|
|
||||||
50% { opacity: 0; }
|
|
||||||
100% { opacity: 1; }
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue