Complete documentation for accessing camera streams from PT-DR1A08G-K1 DVR system.
DVR Model: PT-DR1A08G-K1
IP Address: 192.168.1.2
Active Channels: 1, 4, 5, 6, 7, 8 (6 cameras total)
Authentication: HTTP Digest Auth
Username: admin
Password: admin
Timezone: IST (UTC+5:30)
Resolution: 960x1088 (all channels)
Status: ✅ WORKING - Truly live with <1 second latency
HTTP endpoint provides live JPEG snapshots from all cameras. This is the only method for true real-time streaming (<1 second delay).
http://192.168.1.2/ISAPI/Streaming/channels/{channelID}/picture
- Channel 1:
http://192.168.1.2/ISAPI/Streaming/channels/101/picture
- Channel 4:
http://192.168.1.2/ISAPI/Streaming/channels/401/picture
- Channel 5:
http://192.168.1.2/ISAPI/Streaming/channels/501/picture
- Channel 6:
http://192.168.1.2/ISAPI/Streaming/channels/601/picture
- Channel 7:
http://192.168.1.2/ISAPI/Streaming/channels/701/picture
- Channel 8:
http://192.168.1.2/ISAPI/Streaming/channels/801/picture
HTTP Digest Authentication required:
from requests.auth import HTTPDigestAuth
auth = HTTPDigestAuth('admin', 'admin')
Usage:
python3 snapshot_streamer.py <camera_number>
Examples:
python3 snapshot_streamer.py 1 # Stream camera 1
python3 snapshot_streamer.py 4 # Stream camera 4
python3 snapshot_streamer.py 5 # Stream camera 5
Features:
- Live video display in OpenCV window
- ~5-10 FPS continuous streaming
- <1 second latency
- Press 'q' to quit
- Press 's' to save snapshot
- Automatically creates output directory for saved frames
Code Example:
import cv2
import requests
from requests.auth import HTTPDigestAuth
import time
url = "http://192.168.1.2/ISAPI/Streaming/channels/101/picture"
auth = HTTPDigestAuth('admin', 'admin')
while True:
response = requests.get(url, auth=auth)
if response.status_code == 200:
# Convert to OpenCV image
img_array = np.frombuffer(response.content, np.uint8)
frame = cv2.imdecode(img_array, cv2.IMREAD_COLOR)
cv2.imshow('Live Camera', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
time.sleep(0.1) # ~10 FPS
cv2.destroyAllWindows()
Performance:
- Image size: ~200KB JPEG per frame
- Sustainable FPS: 5-10 FPS
- Latency: <1 second
- Network bandwidth: ~1-2 MB/s per camera
Status: ✅ WORKING - Near-live with ~20-30 minute delay
RTSP endpoint provides video playback from DVR recordings. Due to DVR recording buffer, there is approximately 20-30 minute delay from current time.
rtsp://admin:[email protected]/Streaming/tracks/{trackID}/?starttime=YYYYMMDDThhmmssZ&endtime=YYYYMMDDThhmmssZ
- Camera 1 → Track 101
- Camera 4 → Track 401
- Camera 5 → Track 501
- Camera 6 → Track 601
- Camera 7 → Track 701
- Camera 8 → Track 801
Despite the 'Z' suffix (which typically indicates UTC), the DVR interprets timestamps as local IST time.
# ✅ CORRECT: Use local IST time
from datetime import datetime, timedelta
ist_now = datetime.now() # Local IST time
start_time = ist_now - timedelta(minutes=30)
end_time = ist_now + timedelta(hours=1)
# Format as YYYYMMDDThhmmssZ (values are IST, not UTC!)
start_str = start_time.strftime('%Y%m%dT%H%M%SZ')
end_str = end_time.strftime('%Y%m%dT%H%M%SZ')
# ❌ WRONG: Using UTC time will show old recordings
from datetime import datetime
utc_now = datetime.utcnow() # This will fail!
Usage:
python3 stream_near_live.py <camera_number>
Examples:
python3 stream_near_live.py 1 # Stream camera 1 (30 min delay)
python3 stream_near_live.py 4 # Stream camera 4 (30 min delay)
python3 stream_near_live.py 5 # Stream camera 5 (30 min delay)
Features:
- Video playback in OpenCV window
- Full FPS (15-30 FPS depending on camera)
- H.264 video stream
- ~20-30 minute delay from current time
- Press 'q' to quit
- Press 's' to save snapshot
- Displays frame counter and elapsed time
Code Example:
import cv2
from datetime import datetime, timedelta
# Configuration
HOST = '192.168.1.2'
USERNAME = 'admin'
PASSWORD = 'admin'
TRACK_ID = 101 # Camera 1
# Get IST time and go back 30 minutes
ist_now = datetime.now()
start_time = ist_now - timedelta(minutes=30)
end_time = ist_now + timedelta(hours=1)
# Format timestamps (IST time, not UTC!)
start_str = start_time.strftime('%Y%m%dT%H%M%SZ')
end_str = end_time.strftime('%Y%m%dT%H%M%SZ')
# Build RTSP URL
rtsp_url = f'rtsp://{USERNAME}:{PASSWORD}@{HOST}/Streaming/tracks/{TRACK_ID}/?starttime={start_str}&endtime={end_str}'
# Open stream with OpenCV
cap = cv2.VideoCapture(rtsp_url)
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imshow('Camera', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
Performance:
- FPS: 15-30 FPS (full video stream)
- Resolution: 960x1088
- Codec: H.264
- Latency: ~20-30 minutes
- Network bandwidth: ~1-3 MB/s per camera
playback_manager.py
- Complete playback management:
from playback_manager import DVRPlayback
from datetime import datetime, timedelta
dvr = DVRPlayback('192.168.1.2', 'admin', 'admin')
# Search for recordings
now = datetime.now()
start = now - timedelta(hours=24)
segments = dvr.search_recordings(101, start, now)
# Get recording calendar
calendar = dvr.get_recording_calendar(101, 2025, 10)
# Build RTSP URL
start_time = datetime(2025, 10, 9, 14, 30)
end_time = datetime(2025, 10, 9, 15, 0)
url = dvr.build_rtsp_url(101, start_time, end_time)
extract_rtsp_frames.py
- Extract frames from historical recordings:
# Extract 100 frames from a specific time period
python3 extract_rtsp_frames.py
Script | Purpose | Input | Output |
---|---|---|---|
snapshot_streamer.py |
Live HTTP snapshot streaming | Camera number | Live video window |
stream_near_live.py |
Near-live RTSP streaming | Camera number | Video window (30 min delay) |
playback_manager.py |
Playback management library | Track ID, time range | Recording data, RTSP URLs |
extract_rtsp_frames.py |
Extract frames from recordings | RTSP URL | JPEG frames on disk |
live_stream_viewer.py |
Generic RTSP viewer | Camera number | Video window |
1. Watch Live Camera (truly live, <1s delay):
python3 snapshot_streamer.py 1
2. Watch Near-Live Camera (video stream, 30 min delay):
python3 stream_near_live.py 1
3. Search for Recordings:
from playback_manager import DVRPlayback
from datetime import datetime, timedelta
dvr = DVRPlayback('192.168.1.2', 'admin', 'admin')
now = datetime.now()
yesterday = now - timedelta(days=1)
# Find all recordings from last 24 hours
segments = dvr.search_recordings(101, yesterday, now)
for seg in segments:
print(f"{seg['start_time']} to {seg['end_time']}")
4. Extract Historical Frames:
import cv2
from datetime import datetime
# Specific time from yesterday
start_str = '20251009T143000Z' # Oct 9, 2:30 PM IST
end_str = '20251009T150000Z' # Oct 9, 3:00 PM IST
url = f'rtsp://admin:[email protected]/Streaming/tracks/101/?starttime={start_str}&endtime={end_str}'
cap = cv2.VideoCapture(url)
frame_num = 0
while True:
ret, frame = cap.read()
if not ret:
break
cv2.imwrite(f'frame_{frame_num:04d}.jpg', frame)
frame_num += 1
cap.release()
Attempted:
http://192.168.1.2/ISAPI/Streaming/channels/101/picture?time=20251008T205822Z
Problem:
The DVR ignores the time
parameter completely and always returns the current frame, regardless of the timestamp provided.
Testing:
- Requested frames from Oct 8, 2025 (2 days ago)
- Response always showed current timestamp in image overlay
- MD5 hashes confirmed images were different but all current
- Time parameter has no effect
Conclusion:
HTTP endpoint only supports live snapshots, not historical retrieval.
Attempted:
rtsp://admin:[email protected]/Streaming/tracks/101/
Problem:
Without time parameters, the DVR defaults to the oldest available recording in storage, not the live feed.
Testing:
- Opened stream without starttime/endtime parameters
- Video showed timestamp overlay from December 2024
- This was the oldest recording still in DVR storage
- No way to get "live" feed without time parameters
Conclusion:
RTSP endpoint requires time parameters. Without them, it serves oldest recording, not live stream.
Attempted:
rtsp://admin:[email protected]:554/Streaming/Channels/101
Problem:
Stream opens but produces corrupted/encrypted H.264 data that cannot be decoded.
Errors Observed:
[h264 @ 0x...] A non-intra slice in an IDR NAL unit.
[h264 @ 0x...] decode_slice_header error
[h264 @ 0x...] no frame!
[h264 @ 0x...] Missing reference picture, default is 0
[h264 @ 0x...] non-existing PPS 2 referenced
[h264 @ 0x...] deblocking_filter_idc 6 out of range
Testing:
- cv2.VideoCapture() reports stream as "opened"
- Reports resolution: 960x1088, FPS: 15.0
- Cannot read any frames successfully
- Continuous H.264 decoder errors
- Zero frames extracted
Theory:
This endpoint may be using proprietary encryption or non-standard H.264 implementation. The web UI doesn't use this format either.
Conclusion:
This RTSP format is not usable with standard video players/libraries.
Attempted:
from datetime import datetime
utc_now = datetime.utcnow()
start_str = utc_now.strftime('%Y%m%dT%H%M%SZ')
Problem:
DVR interprets timestamps as local time (IST), causing 5.5 hour offset.
Testing:
- Used UTC timestamps for current time
- Video showed recordings from 1 month ago (September 2025)
- Requested yesterday's recordings, got 2-month-old footage (August 2025)
- Offset matched IST timezone difference (UTC+5:30)
Discovery:
Despite using 'Z' suffix (UTC indicator), DVR expects local IST time values.
Solution:
Use datetime.now()
for local IST time, not datetime.utcnow()
.
Conclusion:
Always use local IST time. UTC causes 5.5 hour timezone mismatch.
Status: Not possible due to DVR recording buffer
Problem:
DVR has ~20-30 minute recording buffer before video is available via RTSP.
Testing:
- Attempted RTSP with current time minus 2 minutes
- Stream failed to open (recording doesn't exist yet)
- Tried current time minus 5, 10, 15 minutes - all failed
- Only works with 20-30 minute delay
Why:
DVR writes recordings to disk with a buffer delay. RTSP can only access finalized recordings, not live buffer.
Workaround:
Use HTTP snapshots for truly live streaming (<1s latency).
Conclusion:
RTSP provides "near-live" at best (~30 min delay). For truly live, use HTTP snapshots.
Attempted formats:
rtsp://192.168.1.2/Streaming/tracks/101/
(no params) → Shows Dec 2024rtsp://192.168.1.2:554/Streaming/tracks/101/
(explicit port) → Same as #1rtsp://192.168.1.2/Streaming/channels/101/
→ Connection refusedrtsp://192.168.1.2:554/Streaming/Channels/101
→ Corrupted H.264rtsp://192.168.1.2/ISAPI/Streaming/channels/101/
→ Connection refused
Conclusion:
Only working format is:
rtsp://admin:[email protected]/Streaming/tracks/{trackID}/?starttime=YYYYMMDDThhmmssZ&endtime=YYYYMMDDThhmmssZ
Endpoint: /ISAPI/ContentMgmt/search
Purpose: Find recording segments within a time range
Request:
<?xml version="1.0" encoding="UTF-8"?>
<CMSearchDescription>
<searchID>unique-uuid-here</searchID>
<trackList>
<trackID>101</trackID>
</trackList>
<timeSpanList>
<timeSpan>
<startTime>2025-10-09T00:00:00Z</startTime>
<endTime>2025-10-10T23:59:59Z</endTime>
</timeSpan>
</timeSpanList>
<maxResults>100</maxResults>
<searchResultPostion>0</searchResultPostion>
<metadataList>
<metadataDescriptor>videoloss</metadataDescriptor>
</metadataList>
</CMSearchDescription>
Response:
<CMSearchResult>
<matchList>
<searchMatchItem>
<trackID>101</trackID>
<startTime>2025-10-09T08:34:21Z</startTime>
<endTime>2025-10-09T13:12:29Z</endTime>
<playbackURI>rtsp://...</playbackURI>
</searchMatchItem>
</matchList>
</CMSearchResult>
Endpoint: /ISAPI/ContentMgmt/record/tracks/{trackID}/dailyDistribution
Purpose: Get list of days with recordings for a specific month
Query Params:
year=2025
month=10
Response:
<trackDailyParam>
<trackID>101</trackID>
<year>2025</year>
<monthIdx>10</monthIdx>
<dayList>
<day>1</day>
<day>2</day>
<day>8</day>
<day>9</day>
<day>10</day>
</dayList>
</trackDailyParam>
Method: HTTP Digest Authentication
Credentials:
- Username: admin
- Password: admin
Python:
from requests.auth import HTTPDigestAuth
auth = HTTPDigestAuth('admin', 'admin')
cURL:
curl --digest -u admin:admin "http://192.168.1.2/ISAPI/Streaming/channels/101/picture"
Resolution: 960x1088 (all channels)
Codec: H.264
FPS: Varies by channel (15-30 FPS)
Audio: PCM μ-law (not compatible with MP4 container)
HTTP Snapshots:
- Per frame: ~200KB JPEG
- At 10 FPS: ~2 MB/s
- At 5 FPS: ~1 MB/s
RTSP Streams:
- H.264 stream: ~1-3 MB/s per camera
- Varies by motion and complexity
Check recording exists:
from playback_manager import DVRPlayback
from datetime import datetime, timedelta
dvr = DVRPlayback('192.168.1.2', 'admin', 'admin')
now = datetime.now()
past = now - timedelta(hours=1)
segments = dvr.search_recordings(101, past, now)
if segments:
print("✅ Recordings exist")
else:
print("❌ No recordings in this time range")
Verify timezone (use IST, not UTC):
# ✅ Correct
ist_now = datetime.now()
# ❌ Wrong
utc_now = datetime.utcnow()
Use sufficient delay for RTSP:
# ✅ Works (30 minute delay)
start_time = datetime.now() - timedelta(minutes=30)
# ❌ Might fail (2 minute delay too recent)
start_time = datetime.now() - timedelta(minutes=2)
Reduce FPS:
time.sleep(0.2) # 5 FPS instead of 10 FPS
Use smaller window:
cv2.resizeWindow('Camera', 640, 360) # Smaller display
Check network:
ping 192.168.1.2
Check OpenCV FFMPEG support:
import cv2
print(cv2.getBuildInformation())
# Look for: Video I/O: FFMPEG: YES
Verify credentials:
curl --digest -u admin:admin "http://192.168.1.2/ISAPI/System/deviceInfo"
Test connectivity:
ping 192.168.1.2
telnet 192.168.1.2 554
For Live Monitoring: Use HTTP snapshots (snapshot_streamer.py
)
- Truly live (<1 second delay)
- Lightweight (~200KB per frame)
- Works reliably at 5-10 FPS
For Video Playback: Use RTSP with time parameters (stream_near_live.py
)
- Full video stream (15-30 FPS)
- ~20-30 minute delay
- H.264 high quality
- Good for reviewing recent events
- True live RTSP (DVR has 20-30 min recording buffer)
- HTTP historical snapshots (time parameter ignored)
- RTSP /Channels/ format (corrupted H.264)
- RTSP without time parameters (shows oldest recording)
Working Scripts:
snapshot_streamer.py
- HTTP live streamingstream_near_live.py
- RTSP near-live streamingplayback_manager.py
- Recording management libraryextract_rtsp_frames.py
- Frame extraction
Documentation:
WORKING_METHODS_SUMMARY.md
- Quick reference guideDVR_STREAMING_GUIDE.md
- This comprehensive guide
Document Version: 1.0
Last Updated: October 10, 2025
DVR Model: PT-DR1A08G-K1
Tested Channels: 1, 4, 5, 6, 7, 8
Python Version: 3.x
Dependencies: opencv-python, requests, numpy