├── demosite ├── robots.txt ├── favicon.ico ├── logo192.png ├── logo512.png ├── aws-exports.json ├── static │ ├── media │ │ ├── playbg.3be50ee9.png │ │ └── logo.e2a890e1.svg │ ├── js │ │ ├── 2.59cad2e3.chunk.js.LICENSE.txt │ │ ├── runtime-main.ec776a9b.js │ │ ├── 3.d0d355a5.chunk.js │ │ ├── 3.d0d355a5.chunk.js.map │ │ ├── runtime-main.ec776a9b.js.map │ │ └── main.c5c7f508.chunk.js │ └── css │ │ ├── 2.373bc5f8.chunk.css │ │ ├── main.3cb751cd.chunk.css │ │ ├── 2.373bc5f8.chunk.css.map │ │ └── main.3cb751cd.chunk.css.map ├── manifest.json ├── asset-manifest.json └── index.html ├── .gitmodules ├── CODE_OF_CONDUCT.md ├── CHANGELOG.md ├── NOTICE.txt ├── LICENSE ├── S3_HLS_Return_Code.h ├── S3_HLS_Pmt.h ├── S3_HLS_Pat.h ├── S3_HLS_H264_Nalu_Types.h ├── S3_HLS_Pes.h ├── S3_HLS_Upload_Thread.h ├── S3_Crypto.h ├── S3_HLS_Queue.h ├── Makefile ├── S3_Crypto.c ├── S3_HLS_TS.h ├── S3_HLS_Return_Code.c ├── S3_HLS_H264_Nalu_Types.c ├── CONTRIBUTING.md ├── S3_HLS_S3_Put_Client.h ├── S3_HLS_Upload_Thread.c ├── S3_HLS_Buffer_Mgr.h ├── S3_HLS_Pat.c ├── S3_HLS_SDK.h ├── S3_HLS_Pmt.c ├── README.md ├── S3_HLS_Queue.c ├── S3_HLS_Buffer_Mgr.c ├── S3_HLS_SDK.c ├── S3_HLS_TS.c └── S3_HLS_Pes.c /demosite/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /demosite/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/ipc-h264-hls-c-sdk/HEAD/demosite/favicon.ico -------------------------------------------------------------------------------- /demosite/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/ipc-h264-hls-c-sdk/HEAD/demosite/logo192.png -------------------------------------------------------------------------------- /demosite/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/ipc-h264-hls-c-sdk/HEAD/demosite/logo512.png -------------------------------------------------------------------------------- /demosite/aws-exports.json: -------------------------------------------------------------------------------- 1 | { 2 | "address": "https://sqmfgk98mf.execute-api.cn-northwest-1.amazonaws.com.cn/playlist.m3u8" 3 | } -------------------------------------------------------------------------------- /demosite/static/media/playbg.3be50ee9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/ipc-h264-hls-c-sdk/HEAD/demosite/static/media/playbg.3be50ee9.png -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "3rd/openssl"] 2 | path = 3rd/openssl 3 | url = https://github.com/openssl/openssl 4 | branch = OpenSSL_1_1_1-stable 5 | [submodule "3rd/curl"] 6 | path = 3rd/curl 7 | url = https://github.com/curl/curl 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | 4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 6 | 7 | ## [2.0] - 2021-07-02 8 | ### Added 9 | - Rebuild components from monolithic architecture to components with different functionality. -------------------------------------------------------------------------------- /demosite/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | This is a sample code for IP Cameras (IPC for short) that use built-in MCU to generate TS format files and upload to S3. 2 | 3 | Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. 4 | Licensed under the Apache License Version 2.0 (the "License"). You may not use this file except 5 | in compliance with the License. A copy of the License is located at http://www.apache.org/licenses/ 6 | or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, 7 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the 8 | specific language governing permissions and limitations under the License. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /S3_HLS_Return_Code.h: -------------------------------------------------------------------------------- 1 | #ifndef __S3_HLS_RETURN_CODE_H__ 2 | #define __S3_HLS_RETURN_CODE_H__ 3 | 4 | #include 5 | 6 | // Return value part 7 | #define S3_HLS_OK 0 8 | #define S3_HLS_OUT_OF_MEMORY -1 9 | #define S3_HLS_INVALID_PARAMETER -2 10 | #define S3_HLS_INVALID_STATUS -3 11 | #define S3_HLS_BUFFER_OVERFLOW -4 12 | #define S3_HLS_BUFFER_EMPTY -5 13 | #define S3_HLS_LOCK_FAILED -6 14 | #define S3_HLS_UNKNOWN_INTERNAL_ERROR -7 15 | #define S3_HLS_QUEUE_FULL -8 16 | #define S3_HLS_QUEUE_EMPTY -9 17 | #define S3_HLS_HTTP_CLIENT_INIT_ERROR -10 18 | #define S3_HLS_THREAD_ALREADY_STOPPED -11 19 | #define S3_HLS_UPLOAD_FAILED -12 20 | 21 | #define S3_HLS_TS_COUNTER_INDEX 3 22 | 23 | #define S3_HLS_Video_PID 0x100 24 | #define S3_HLS_Audio_PID 0x101 25 | 26 | #define S3_HLS_TS_PACKET_SIZE 188 27 | 28 | extern uint8_t const_fill_word[S3_HLS_TS_PACKET_SIZE]; 29 | #endif 30 | -------------------------------------------------------------------------------- /demosite/asset-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "main.css": "/static/css/main.3cb751cd.chunk.css", 4 | "main.js": "/static/js/main.c5c7f508.chunk.js", 5 | "main.js.map": "/static/js/main.c5c7f508.chunk.js.map", 6 | "runtime-main.js": "/static/js/runtime-main.ec776a9b.js", 7 | "runtime-main.js.map": "/static/js/runtime-main.ec776a9b.js.map", 8 | "static/css/2.373bc5f8.chunk.css": "/static/css/2.373bc5f8.chunk.css", 9 | "static/js/2.59cad2e3.chunk.js": "/static/js/2.59cad2e3.chunk.js", 10 | "static/js/2.59cad2e3.chunk.js.map": "/static/js/2.59cad2e3.chunk.js.map", 11 | "static/js/3.d0d355a5.chunk.js": "/static/js/3.d0d355a5.chunk.js", 12 | "static/js/3.d0d355a5.chunk.js.map": "/static/js/3.d0d355a5.chunk.js.map", 13 | "index.html": "/index.html", 14 | "static/css/2.373bc5f8.chunk.css.map": "/static/css/2.373bc5f8.chunk.css.map", 15 | "static/css/main.3cb751cd.chunk.css.map": "/static/css/main.3cb751cd.chunk.css.map", 16 | "static/js/2.59cad2e3.chunk.js.LICENSE.txt": "/static/js/2.59cad2e3.chunk.js.LICENSE.txt", 17 | "static/media/logo.e2a890e1.svg": "/static/media/logo.e2a890e1.svg", 18 | "static/media/playbg.3be50ee9.png": "/static/media/playbg.3be50ee9.png" 19 | }, 20 | "entrypoints": [ 21 | "static/js/runtime-main.ec776a9b.js", 22 | "static/css/2.373bc5f8.chunk.css", 23 | "static/js/2.59cad2e3.chunk.js", 24 | "static/css/main.3cb751cd.chunk.css", 25 | "static/js/main.c5c7f508.chunk.js" 26 | ] 27 | } -------------------------------------------------------------------------------- /S3_HLS_Pmt.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_PMT_H__ 20 | #define __S3_HLS_PMT_H__ 21 | 22 | #include "stdint.h" 23 | 24 | #ifdef __cplusplus 25 | #if __cplusplus 26 | extern "C" { 27 | #endif 28 | #endif /* End of #ifdef __cplusplus */ 29 | 30 | #define ERR_S3_HLS_H264_PMT_NULL_BUFFER -1 31 | #define ERR_S3_HLS_H264_PMT_INVALID_BUFFER_LENGTH -2 32 | 33 | /* 34 | * write PMT header to buffer 35 | * as pmt is fixed for given stream will only verify size 36 | * returns number of bytes written to the buffer 37 | */ 38 | int32_t S3_HLS_H264_PMT_Write_To_Buffer(); 39 | void S3_HLS_PMT_Reset_Counter(); 40 | 41 | #ifdef __cplusplus 42 | #if __cplusplus 43 | } 44 | #endif 45 | #endif /* End of #ifdef __cplusplus */ 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /S3_HLS_Pat.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_PAT_H__ 20 | #define __S3_HLS_PAT_H__ 21 | 22 | #include "stdint.h" 23 | #include "S3_HLS_Buffer_Mgr.h" 24 | 25 | #ifdef __cplusplus 26 | #if __cplusplus 27 | extern "C" { 28 | #endif 29 | #endif /* End of #ifdef __cplusplus */ 30 | 31 | #define ERR_S3_HLS_H264_PAT_NULL_BUFFER -1 32 | #define ERR_S3_HLS_H264_PAT_INVALID_BUFFER_LENGTH -2 33 | 34 | /* 35 | * write PAT header to buffer 36 | * as pat is fixed for given stream will only verify size 37 | * returns number of bytes written to the buffer 38 | */ 39 | int32_t S3_HLS_H264_PAT_Write_To_Buffer(S3_HLS_BUFFER_CTX* buffer_ctx); 40 | void S3_HLS_PAT_Reset_Counter(); 41 | 42 | #ifdef __cplusplus 43 | #if __cplusplus 44 | } 45 | #endif 46 | #endif /* End of #ifdef __cplusplus */ 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /S3_HLS_H264_Nalu_Types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_H264_NALU_TYPES_H__ 20 | #define __S3_HLS_H264_NALU_TYPES_H__ 21 | 22 | #include "stdint.h" 23 | #include "S3_HLS_SDK.h" 24 | 25 | #ifdef __cplusplus 26 | #if __cplusplus 27 | extern "C" { 28 | #endif 29 | #endif /* End of #ifdef __cplusplus */ 30 | 31 | typedef enum { 32 | S3_HLS_H264E_NALU_UNSPECIFIED = 0, 33 | S3_HLS_H264E_NALU_NON_IDR = 1, 34 | S3_HLS_H264E_NALU_DPA = 2, 35 | S3_HLS_H264E_NALU_DPB = 3, 36 | S3_HLS_H264E_NALU_DPC = 4, 37 | S3_HLS_H264E_NALU_IDR = 5, 38 | S3_HLS_H264E_NALU_SEI = 6, 39 | S3_HLS_H264E_NALU_SPS = 7, 40 | S3_HLS_H264E_NALU_PPS = 8, 41 | S3_HLS_H264E_NALU_AUD = 9, // Access Unit Delimeter 42 | S3_HLS_H264E_NALU_END_SEQ = 10, 43 | S3_HLS_H264E_NALU_END_STREAM = 11, 44 | S3_HLS_H264E_NALU_FILLER = 12 45 | } S3_HLS_H264E_NALU_TYPE_E; 46 | 47 | S3_HLS_H264E_NALU_TYPE_E S3_HLS_H264_Nalu_Type(S3_HLS_FRAME_ITEM* item); 48 | 49 | #ifdef __cplusplus 50 | #if __cplusplus 51 | } 52 | #endif 53 | #endif /* End of #ifdef __cplusplus */ 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /S3_HLS_Pes.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_H264_PES_H__ 20 | #define __S3_HLS_H264_PES_H__ 21 | 22 | #include "S3_HLS_SDK.h" 23 | #include "S3_HLS_Buffer_Mgr.h" 24 | 25 | #ifdef __cplusplus 26 | #if __cplusplus 27 | extern "C" { 28 | #endif 29 | #endif /* End of #ifdef __cplusplus */ 30 | 31 | #define ERR_S3_HLS_H264_PES_NULL_BUFFER -1 32 | #define ERR_S3_HLS_H264_PES_INVALID_BUFFER_LENGTH -2 33 | 34 | /* 35 | * write PES header to buffer 36 | * internal execution will set stream types for different stream type 37 | * returns number of bytes written to the buffer 38 | */ 39 | int32_t S3_HLS_Pes_Write_Video_Frame(S3_HLS_BUFFER_CTX* ctx, S3_HLS_FRAME_PACK* pack); 40 | 41 | /* 42 | * write PES header to buffer 43 | * internal execution will set stream types for different stream type 44 | * returns number of bytes written to the buffer 45 | */ 46 | int32_t S3_HLS_Pes_Write_Audio_Frame(S3_HLS_BUFFER_CTX* ctx, S3_HLS_FRAME_PACK* pack); 47 | 48 | #ifdef __cplusplus 49 | #if __cplusplus 50 | } 51 | #endif 52 | #endif /* End of #ifdef __cplusplus */ 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /S3_HLS_Upload_Thread.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_UPLOAD_THREAD_H__ 20 | #define __S3_HLS_UPLOAD_THREAD_H__ 21 | 22 | #include "stdint.h" 23 | #include "pthread.h" 24 | 25 | #ifdef __cplusplus 26 | #if __cplusplus 27 | extern "C" { 28 | #endif 29 | #endif /* End of #ifdef __cplusplus */ 30 | 31 | typedef void (*THREAD_RUN)(); 32 | 33 | typedef struct s3_hls_thread_s { 34 | pthread_t thread_id; 35 | uint8_t exit_flag; 36 | 37 | THREAD_RUN run; 38 | } S3_HLS_THREAD_CTX; 39 | 40 | /* 41 | * Initialize resources and create thread context but not start the thread 42 | */ 43 | S3_HLS_THREAD_CTX* S3_HLS_Upload_Thread_Initialize(THREAD_RUN call_back); 44 | 45 | /* 46 | * Start thread in given thread ctx 47 | */ 48 | int32_t S3_HLS_Upload_Thread_Start(S3_HLS_THREAD_CTX* ctx); 49 | 50 | /* 51 | * Stop thread and free ctx object 52 | * User should not use ctx after calling this function 53 | */ 54 | int32_t S3_HLS_Upload_Thread_Stop(S3_HLS_THREAD_CTX* ctx); 55 | 56 | #ifdef __cplusplus 57 | #if __cplusplus 58 | } 59 | #endif 60 | #endif /* End of #ifdef __cplusplus */ 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /S3_Crypto.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_CRYPTO_H__ 20 | #define __S3_CRYPTO_H__ 21 | 22 | #include "stdint.h" 23 | 24 | #include "openssl/evp.h" 25 | #include "openssl/sha.h" 26 | #include "openssl/hmac.h" 27 | 28 | #ifdef __cplusplus 29 | #if __cplusplus 30 | extern "C" { 31 | #endif 32 | #endif /* End of #ifdef __cplusplus */ 33 | 34 | #define S3_CRYPTO_OK 0 35 | #define S3_CRYPTO_FAILED -1 36 | #define S3_SHA256_DIGEST_LENGTH 32 37 | 38 | typedef SHA256_CTX S3_SHA256_CTX; 39 | typedef HMAC_CTX S3_HMAC_SHA256_CTX; 40 | 41 | typedef unsigned char S3_SHA256_HASH[S3_SHA256_DIGEST_LENGTH]; 42 | 43 | int32_t S3_SHA256_Init(S3_SHA256_CTX* ctx); 44 | 45 | int32_t S3_SHA256_Update(S3_SHA256_CTX* ctx, const void *data, uint32_t length); 46 | 47 | int32_t S3_SHA256_Final(S3_SHA256_CTX *ctx, S3_SHA256_HASH result); 48 | 49 | int32_t S3_HMAC_SHA256(const void* key, unsigned int key_length, const void* data, unsigned int data_length, S3_SHA256_HASH result); 50 | 51 | #ifdef __cplusplus 52 | #if __cplusplus 53 | } 54 | #endif 55 | #endif /* End of #ifdef __cplusplus */ 56 | 57 | #endif 58 | 59 | -------------------------------------------------------------------------------- /demosite/static/js/2.59cad2e3.chunk.js.LICENSE.txt: -------------------------------------------------------------------------------- 1 | /* 2 | object-assign 3 | (c) Sindre Sorhus 4 | @license MIT 5 | */ 6 | 7 | /*! 8 | Copyright (c) 2017 Jed Watson. 9 | Licensed under the MIT License (MIT), see 10 | http://jedwatson.github.io/classnames 11 | */ 12 | 13 | /** 14 | * A better abstraction over CSS. 15 | * 16 | * @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present 17 | * @website https://github.com/cssinjs/jss 18 | * @license MIT 19 | */ 20 | 21 | /** @license React v0.20.1 22 | * scheduler.production.min.js 23 | * 24 | * Copyright (c) Facebook, Inc. and its affiliates. 25 | * 26 | * This source code is licensed under the MIT license found in the 27 | * LICENSE file in the root directory of this source tree. 28 | */ 29 | 30 | /** @license React v16.13.1 31 | * react-is.production.min.js 32 | * 33 | * Copyright (c) Facebook, Inc. and its affiliates. 34 | * 35 | * This source code is licensed under the MIT license found in the 36 | * LICENSE file in the root directory of this source tree. 37 | */ 38 | 39 | /** @license React v17.0.1 40 | * react-dom.production.min.js 41 | * 42 | * Copyright (c) Facebook, Inc. and its affiliates. 43 | * 44 | * This source code is licensed under the MIT license found in the 45 | * LICENSE file in the root directory of this source tree. 46 | */ 47 | 48 | /** @license React v17.0.1 49 | * react-is.production.min.js 50 | * 51 | * Copyright (c) Facebook, Inc. and its affiliates. 52 | * 53 | * This source code is licensed under the MIT license found in the 54 | * LICENSE file in the root directory of this source tree. 55 | */ 56 | 57 | /** @license React v17.0.1 58 | * react-jsx-runtime.production.min.js 59 | * 60 | * Copyright (c) Facebook, Inc. and its affiliates. 61 | * 62 | * This source code is licensed under the MIT license found in the 63 | * LICENSE file in the root directory of this source tree. 64 | */ 65 | 66 | /** @license React v17.0.1 67 | * react.production.min.js 68 | * 69 | * Copyright (c) Facebook, Inc. and its affiliates. 70 | * 71 | * This source code is licensed under the MIT license found in the 72 | * LICENSE file in the root directory of this source tree. 73 | */ 74 | 75 | //! moment.js 76 | -------------------------------------------------------------------------------- /S3_HLS_Queue.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_QUEUE_H__ 20 | #define __S3_HLS_QUEUE_H__ 21 | 22 | #include "stdint.h" 23 | #include "time.h" 24 | 25 | #include "S3_HLS_Buffer_Mgr.h" 26 | 27 | #ifdef __cplusplus 28 | #if __cplusplus 29 | extern "C" { 30 | #endif 31 | #endif /* End of #ifdef __cplusplus */ 32 | 33 | #define S3_HLS_MAX_PARTS_IN_BUFFER 10 34 | 35 | typedef struct s3_hls_queue_s { 36 | S3_HLS_BUFFER_PART_CTX queue[S3_HLS_MAX_PARTS_IN_BUFFER]; 37 | uint8_t queue_pos; 38 | uint8_t queue_length; 39 | 40 | pthread_mutex_t s3_hls_queue_lock; 41 | } S3_HLS_QUEUE_CTX; 42 | 43 | S3_HLS_QUEUE_CTX* S3_HLS_Initialize_Queue(); 44 | 45 | int32_t S3_HLS_Add_To_Queue(S3_HLS_QUEUE_CTX* ctx, uint8_t* first_part, uint32_t first_length, uint8_t* second_part, uint32_t second_length, time_t timestamp); 46 | 47 | int32_t S3_HLS_Release_Queue(S3_HLS_QUEUE_CTX* ctx); 48 | 49 | int32_t S3_HLS_Finalize_Queue(S3_HLS_QUEUE_CTX* ctx); 50 | 51 | int32_t S3_HLS_Get_Item_From_Queue(S3_HLS_QUEUE_CTX* ctx, S3_HLS_BUFFER_PART_CTX* buffer_ctx); 52 | 53 | #ifdef __cplusplus 54 | #if __cplusplus 55 | } 56 | #endif 57 | #endif /* End of #ifdef __cplusplus */ 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /demosite/static/js/runtime-main.ec776a9b.js: -------------------------------------------------------------------------------- 1 | !function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=r[2],p=0,s=[];p 20 | 21 | #include "S3_Crypto.h" 22 | #include "S3_HLS_Return_Code.h" 23 | 24 | int32_t S3_SHA256_Init(S3_SHA256_CTX* ctx) { 25 | if(NULL == ctx) { 26 | return S3_HLS_INVALID_PARAMETER; 27 | } 28 | 29 | return SHA256_Init(ctx); 30 | } 31 | 32 | int32_t S3_SHA256_Update(S3_SHA256_CTX* ctx, const void *data, uint32_t length) { 33 | if(NULL == ctx) { 34 | return S3_HLS_INVALID_PARAMETER; 35 | } 36 | 37 | return SHA256_Update(ctx, data, length); 38 | } 39 | 40 | int32_t S3_SHA256_Final(S3_SHA256_CTX *ctx, S3_SHA256_HASH result) { 41 | if(NULL == ctx) { 42 | return S3_HLS_INVALID_PARAMETER; 43 | } 44 | 45 | return SHA256_Final(result, ctx); 46 | } 47 | 48 | int32_t S3_HMAC_SHA256(const void* key, unsigned int key_length, const void* data, unsigned int data_length, S3_SHA256_HASH result){ 49 | const EVP_MD * engine = EVP_sha256(); 50 | unsigned int ret_length = 0; 51 | 52 | HMAC_CTX* ctx = NULL; 53 | ctx = HMAC_CTX_new(); 54 | if(NULL == ctx) { 55 | return S3_CRYPTO_FAILED; 56 | } 57 | 58 | HMAC_Init_ex(ctx, key, key_length, engine, NULL); 59 | HMAC_Update(ctx, (unsigned char*)data, data_length); 60 | 61 | HMAC_Final(ctx, result, &ret_length); 62 | 63 | HMAC_CTX_free(ctx); 64 | 65 | if(SHA256_DIGEST_LENGTH != ret_length) { 66 | return S3_CRYPTO_FAILED; 67 | } 68 | 69 | return S3_CRYPTO_OK; 70 | } 71 | -------------------------------------------------------------------------------- /S3_HLS_TS.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_H264_PMT_H__ 20 | #define __S3_HLS_H264_PMT_H__ 21 | 22 | #include "stdint.h" 23 | 24 | #ifdef __cplusplus 25 | #if __cplusplus 26 | extern "C" { 27 | #endif 28 | #endif /* End of #ifdef __cplusplus */ 29 | 30 | /* 31 | * Call this function to write TS header and adoption field to buffer 32 | */ 33 | int32_t S3_HLS_TS_Write_To_Buffer(); 34 | 35 | /* 36 | * Call this function to set pid before write TS Header to buffer 37 | */ 38 | void S3_HLS_TS_Set_Pid(uint32_t pid); 39 | 40 | /* 41 | * Call this function to set payload start flag before write TS Header to buffer 42 | */ 43 | void S3_HLS_TS_Set_Payload_Start(); 44 | 45 | /* 46 | * Call this function to set random access flag before write TS Header to buffer 47 | */ 48 | void S3_HLS_TS_Set_Random_Access(); 49 | 50 | /* 51 | * Call this function to set PCR flag and value before write TS Header to buffer 52 | */ 53 | void S3_HLS_TS_Set_PCR(uint64_t input_timestamp); 54 | 55 | /* 56 | * Call this function to fill adoption fields if data_length is less than remaining bytes. 57 | * Call this function before write TS Header to buffer and after set random access and pcr 58 | */ 59 | void S3_HLS_TS_Fill_Remaining_Length(uint32_t data_length); 60 | 61 | /* 62 | * Call this function to reset the counter field in ts header 63 | */ 64 | void S3_HLS_TS_Reset_Counter(uint32_t pid); 65 | 66 | #ifdef __cplusplus 67 | #if __cplusplus 68 | } 69 | #endif 70 | #endif /* End of #ifdef __cplusplus */ 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /S3_HLS_Return_Code.c: -------------------------------------------------------------------------------- 1 | #include "S3_HLS_Return_Code.h" 2 | 3 | uint8_t const_fill_word[S3_HLS_TS_PACKET_SIZE] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 4 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 5 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 6 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 7 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 8 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 9 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 10 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 11 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 12 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 13 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 14 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 15 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 16 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 17 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 18 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 19 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 20 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 21 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 22 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 23 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 24 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 25 | , 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 26 | , 0xFF, 0xFF, 0xFF, 0xFF }; 27 | -------------------------------------------------------------------------------- /S3_HLS_H264_Nalu_Types.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #include "stdlib.h" 20 | 21 | #include "S3_HLS_H264_Nalu_Types.h" 22 | 23 | #define S3_HLS_NALU_BYTE_POS 5 24 | #define S3_HLS_H264_NALU_BITS 0x1F 25 | 26 | const uint8_t h264_start_code[4] = { 0x00, 0x00, 0x00, 0x01 }; 27 | 28 | S3_HLS_H264E_NALU_TYPE_E S3_HLS_H264_Nalu_Type(S3_HLS_FRAME_ITEM* item) { 29 | if(NULL == item->second_part_start && 0 != item->second_part_length) { 30 | return S3_HLS_H264E_NALU_UNSPECIFIED; 31 | } 32 | 33 | if(S3_HLS_NALU_BYTE_POS > item->first_part_length + item->second_part_length) { 34 | return S3_HLS_H264E_NALU_UNSPECIFIED; 35 | } 36 | 37 | int i = 0; 38 | while(i < item->first_part_length && i < S3_HLS_NALU_BYTE_POS - 1) { 39 | if(h264_start_code[i] != item->first_part_start[i]) { 40 | return S3_HLS_H264E_NALU_UNSPECIFIED; 41 | } 42 | 43 | i++; 44 | } 45 | 46 | while(i < S3_HLS_NALU_BYTE_POS - 1) { 47 | // only enter this piece of code when first part length is not enought for finding the nalu byte 48 | if(h264_start_code[i] != item->second_part_start[i - item->first_part_length]){ 49 | return S3_HLS_H264E_NALU_UNSPECIFIED; 50 | } 51 | 52 | i++; 53 | } 54 | 55 | if(i > item->first_part_length) { 56 | return item->second_part_start[i - item->first_part_length] & S3_HLS_H264_NALU_BITS; 57 | } else { 58 | return item->first_part_start[i] & S3_HLS_H264_NALU_BITS; 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /demosite/static/media/logo.e2a890e1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Group 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /demosite/static/css/2.373bc5f8.chunk.css: -------------------------------------------------------------------------------- 1 | .react-spinner-loader-swing div{border-radius:50%;float:left;height:1em;width:1em}.react-spinner-loader-swing div:first-of-type{background:linear-gradient(90deg,#385c78 0,#325774)}.react-spinner-loader-swing div:nth-of-type(2){background:linear-gradient(90deg,#325774 0,#47536a)}.react-spinner-loader-swing div:nth-of-type(3){background:linear-gradient(90deg,#4a5369 0,#6b4d59)}.react-spinner-loader-swing div:nth-of-type(4){background:linear-gradient(90deg,#744c55 0,#954646)}.react-spinner-loader-swing div:nth-of-type(5){background:linear-gradient(90deg,#9c4543 0,#bb4034)}.react-spinner-loader-swing div:nth-of-type(6){background:linear-gradient(90deg,#c33f31 0,#d83b27)}.react-spinner-loader-swing div:nth-of-type(7){background:linear-gradient(90deg,#da3b26 0,#db412c)}.react-spinner-loader-shadow{clear:left;padding-top:1.5em}.react-spinner-loader-shadow div{-webkit-filter:blur(1px);filter:blur(1px);float:left;width:1em;height:.25em;border-radius:50%;background:#e3dbd2}.react-spinner-loader-shadow .react-spinner-loader-shadow-l{background:#d5d8d6}.react-spinner-loader-shadow .react-spinner-loader-shadow-r{background:#eed3ca}@keyframes ball-l{0%,50%{transform:rotate(0) translateX(0)}to{transform:rotate(50deg) translateX(-2.5em)}}@keyframes ball-r{0%{transform:rotate(-50deg) translateX(2.5em)}50%,to{transform:rotate(0) translateX(0)}}@keyframes shadow-l-n{0%,50%{opacity:.5;transform:translateX(0)}to{opacity:.125;transform:translateX(-1.75em)}}@keyframes shadow-r-n{0%{opacity:.125;transform:translateX(1.75em)}50%,to{opacity:.5;transform:translateX(0)}}.react-spinner-loader-swing-l{animation:ball-l .425s ease-in-out infinite alternate}.react-spinner-loader-swing-r{animation:ball-r .425s ease-in-out infinite alternate}.react-spinner-loader-shadow-l{animation:shadow-l-n .425s ease-in-out infinite alternate}.react-spinner-loader-shadow-r{animation:shadow-r-n .425s ease-in-out infinite alternate}.react-spinner-loader-svg-calLoader{width:230px;height:230px;transform-origin:115px 115px;animation:loader-spin 1.4s linear infinite;-webkit-animation:loader-spin 1.4s linear infinite}.react-spinner-loader-svg-cal-loader__path{animation:loader-path 1.4s ease-in-out infinite;-webkit-animation:loader-path 1.4s ease-in-out infinite}@keyframes loader-spin{to{transform:rotate(1turn)}}@keyframes loader-path{0%{stroke-dasharray:0,580,0,0,0,0,0,0,0}50%{stroke-dasharray:0,450,10,30,10,30,10,30,10}to{stroke-dasharray:0,580,0,0,0,0,0,0,0}}.react-spinner-loader-svg svg{transform-origin:50% 65%}.react-spinner-loader-svg svg polygon{stroke-dasharray:17;animation:dash 2.5s cubic-bezier(.35,.04,.63,.95) infinite}@keyframes dash{to{stroke-dashoffset:136}}@keyframes rotate{to{transform:rotate(1turn)}} 2 | /*# sourceMappingURL=2.373bc5f8.chunk.css.map */ -------------------------------------------------------------------------------- /demosite/index.html: -------------------------------------------------------------------------------- 1 | IP Camera Demo
-------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /S3_HLS_S3_Put_Client.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_S3_PUT_CLIENT_H__ 20 | #define __S3_HLS_S3_PUT_CLIENT_H__ 21 | 22 | #include 23 | #include 24 | 25 | #include "curl/curl.h" 26 | 27 | #define S3_HLS_MAX_KEY_LENGTH 1024 28 | 29 | #define S3_HLS_TIMESTAMP_HEADER_BUFFER_SIZE 28 // "%04d%02d%02dT%02d%02d%02dZ" 30 | #define S3_HLS_DATE_BUFFER_SIZE 9 // "%04d%02d%02d" 31 | #define S3_HLS_CONTENT_HASH_HEADER_LENGTH 86 // x-amz-content-sha256:...... 32 | 33 | #ifdef __cplusplus 34 | #if __cplusplus 35 | extern "C" { 36 | #endif 37 | #endif /* End of #ifdef __cplusplus */ 38 | 39 | typedef struct s3_hls_client_s { 40 | char* endpoint; 41 | uint8_t free_endpoint; 42 | 43 | char* uri; 44 | 45 | char timestamp_buffer[S3_HLS_TIMESTAMP_HEADER_BUFFER_SIZE]; 46 | char date_buffer[S3_HLS_DATE_BUFFER_SIZE]; 47 | char object_key[S3_HLS_MAX_KEY_LENGTH]; 48 | 49 | char* host_header; 50 | 51 | char content_hash[S3_HLS_CONTENT_HASH_HEADER_LENGTH]; 52 | 53 | char* string_to_sign; 54 | 55 | char* region; 56 | 57 | char* secret_access_key; 58 | uint32_t secret_access_key_length; 59 | 60 | char* token_header; 61 | uint32_t token_header_length; 62 | 63 | char* auth_header; 64 | uint32_t auth_header_length; 65 | 66 | char* access_key; 67 | 68 | char* tag_header; 69 | uint32_t tag_header_length; 70 | 71 | pthread_mutex_t credential_lock; 72 | 73 | CURL* curl; 74 | } S3_HLS_CLIENT_CTX; 75 | 76 | /* 77 | * 78 | */ 79 | S3_HLS_CLIENT_CTX* S3_HLS_Client_Initialize(char* region, char* bucket, char* endpoint); 80 | 81 | /* 82 | * 83 | */ 84 | int32_t S3_HLS_Client_Finalize(S3_HLS_CLIENT_CTX* ctx); 85 | 86 | /* 87 | * 88 | */ 89 | int32_t S3_HLS_Client_Set_Tag(S3_HLS_CLIENT_CTX* ctx, char* object_tag); 90 | 91 | /* 92 | * 93 | */ 94 | int32_t S3_HLS_Client_Set_Credential(S3_HLS_CLIENT_CTX* ctx, char* ak, char* sk, char* token); 95 | 96 | /* 97 | * 98 | */ 99 | int32_t S3_HLS_Client_Upload_Buffer(S3_HLS_CLIENT_CTX* ctx, char* object_key, uint8_t* first_data, uint32_t first_length, uint8_t* second_data, uint32_t second_length); 100 | 101 | /* 102 | * 103 | */ 104 | int32_t S3_HLS_Client_Upload_Object(S3_HLS_CLIENT_CTX* ctx, char* object_key, uint8_t* data, uint32_t length); 105 | 106 | #ifdef __cplusplus 107 | #if __cplusplus 108 | } 109 | #endif 110 | #endif /* End of #ifdef __cplusplus */ 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /S3_HLS_Upload_Thread.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include "S3_HLS_Upload_Thread.h" 24 | #include "S3_HLS_Return_Code.h" 25 | 26 | //#define S3_HLS_THREAD_DEBUG 27 | 28 | #ifdef S3_HLS_THREAD_DEBUG 29 | #define THREAD_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 30 | #else 31 | #define THREAD_DEBUG(x, ...) 32 | #endif 33 | 34 | 35 | static void S3_HLS_Thread_Loop(void* ctx) { 36 | THREAD_DEBUG("Thread Initialized!\n"); 37 | if(NULL == ctx) { 38 | THREAD_DEBUG("Cannot find thread context!\n"); 39 | return; 40 | } 41 | 42 | S3_HLS_THREAD_CTX* thread_ctx = (S3_HLS_THREAD_CTX*)ctx; 43 | while(!thread_ctx->exit_flag) { 44 | printf("Thread Run!\n"); 45 | thread_ctx->run(); 46 | } 47 | } 48 | 49 | /* 50 | * Initialize resources and create thread context but not start the thread 51 | */ 52 | S3_HLS_THREAD_CTX* S3_HLS_Upload_Thread_Initialize(THREAD_RUN call_back) { 53 | if(NULL == call_back) 54 | return NULL; 55 | 56 | THREAD_DEBUG("Creating thread context!\n"); 57 | S3_HLS_THREAD_CTX* ctx = (S3_HLS_THREAD_CTX*)malloc(sizeof(S3_HLS_THREAD_CTX)); 58 | if(NULL == ctx) { 59 | THREAD_DEBUG("Allocate memory for thread context failed!\n"); 60 | return NULL; 61 | } 62 | 63 | ctx->exit_flag = 0; 64 | ctx->run = call_back; 65 | 66 | THREAD_DEBUG("Creating thread context finished!\n"); 67 | return ctx; 68 | } 69 | 70 | /* 71 | * Start thread in given thread ctx 72 | */ 73 | int32_t S3_HLS_Upload_Thread_Start(S3_HLS_THREAD_CTX* ctx) { 74 | if(NULL == ctx) 75 | return S3_HLS_INVALID_PARAMETER; 76 | 77 | THREAD_DEBUG("Starting thread!\n"); 78 | int32_t ret = pthread_create(&ctx->thread_id, NULL, (void*)S3_HLS_Thread_Loop, ctx); 79 | if(0 != ret) { 80 | free(ctx); 81 | return S3_HLS_UNKNOWN_INTERNAL_ERROR; 82 | } 83 | 84 | THREAD_DEBUG("Starting thread finished %d!\n", ctx->thread_id); 85 | 86 | return S3_HLS_OK; 87 | } 88 | 89 | /* 90 | * Stop thread and free ctx object 91 | * User should not use ctx after calling this function 92 | */ 93 | int32_t S3_HLS_Upload_Thread_Stop(S3_HLS_THREAD_CTX* ctx) { 94 | if(NULL == ctx) 95 | return S3_HLS_INVALID_PARAMETER; 96 | 97 | if(ctx->exit_flag) 98 | return S3_HLS_THREAD_ALREADY_STOPPED; 99 | 100 | ctx->exit_flag = 1; 101 | 102 | pthread_join(ctx->thread_id, NULL); 103 | 104 | free(ctx); 105 | 106 | return S3_HLS_OK; 107 | } 108 | -------------------------------------------------------------------------------- /S3_HLS_Buffer_Mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | #ifndef __S3_HLS_BUFFER_MGR_H__ 20 | #define __S3_HLS_BUFFER_MGR_H__ 21 | 22 | #include "stdint.h" 23 | #include "time.h" 24 | #include 25 | 26 | #ifdef __cplusplus 27 | #if __cplusplus 28 | extern "C" { 29 | #endif 30 | #endif /* End of #ifdef __cplusplus */ 31 | 32 | typedef struct s3_hls_buffer_part_handle_s { 33 | uint8_t* first_part_start; 34 | uint32_t first_part_length; 35 | 36 | uint8_t* second_part_start; 37 | uint32_t second_part_length; 38 | 39 | time_t timestamp; 40 | } S3_HLS_BUFFER_PART_CTX; 41 | 42 | typedef void (*BUFFER_CALL_BACK)(S3_HLS_BUFFER_PART_CTX* ctx); 43 | 44 | typedef struct s3_hls_buffer_s { 45 | uint8_t* buffer_start; 46 | uint32_t total_length; 47 | 48 | uint8_t* used_start; 49 | uint32_t used_length; 50 | 51 | uint8_t* last_flush; 52 | time_t last_flush_timestamp; 53 | 54 | pthread_mutex_t buffer_lock; 55 | 56 | BUFFER_CALL_BACK call_back; 57 | } S3_HLS_BUFFER_CTX; 58 | 59 | /* 60 | * Buffer manager is a central managememnt of video and audio buffer that is cached for sending to S3 61 | * Initialize will allocate memory buffer for given size 62 | */ 63 | S3_HLS_BUFFER_CTX* S3_HLS_Initialize_Buffer(uint32_t buffer_size, BUFFER_CALL_BACK function_pointer); 64 | 65 | /* 66 | * Free up memory allocated for buffer 67 | * After calling finalize, user shoud not use ctx any more 68 | */ 69 | void S3_HLS_Finalize_Buffer(S3_HLS_BUFFER_CTX* ctx); 70 | 71 | /* 72 | * Flush will call the call back function with newly added data in buffer 73 | * The data is stored in a S3_HLS_BUFFER_PART_CTX struct when calling the call back function 74 | * Data will have a timestamp of when last Flush is called and passed in 75 | * If there is no data in buffer, calling flush will only update the timestamp 76 | */ 77 | int32_t S3_HLS_Flush_Buffer(S3_HLS_BUFFER_CTX* ctx); 78 | 79 | /* 80 | * Clear buffer will release buffer that provided by flush buffer 81 | * After clear the buffer, it can be reused by other input 82 | */ 83 | int32_t S3_HLS_Clear_Buffer(S3_HLS_BUFFER_CTX* buffer_ctx, S3_HLS_BUFFER_PART_CTX* ctx); 84 | 85 | /* 86 | * Put data into buffer 87 | * Return number of bytes written to buffer if success 88 | * Return negative error code if failed 89 | */ 90 | int32_t S3_HLS_Put_To_Buffer(S3_HLS_BUFFER_CTX* ctx, uint8_t* data, uint32_t length); 91 | 92 | int32_t S3_HLS_Lock_Buffer(S3_HLS_BUFFER_CTX* ctx); 93 | 94 | int32_t S3_HLS_Unlock_Buffer(S3_HLS_BUFFER_CTX* ctx); 95 | 96 | #ifdef __cplusplus 97 | #if __cplusplus 98 | } 99 | #endif 100 | #endif /* End of #ifdef __cplusplus */ 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /S3_HLS_Pat.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | /* 19 | *. Format: 20 | * 21 | * TS Header 4 bytes 22 | * 0x47 sync 23 | * 0x40 payload_start + PID 0x0000 24 | * 0x00 pid 25 | * 0x30 contains payload data (0x10 always exists) and adaption field (0x20) 26 | * 0x00 adaption length field 27 | * 28 | * PAT Header 29 | * 0x00 table_id 0x00 for PAT 30 | * 0xb0 0b1 (0x80) for section_syntax_indicator, 0b0 (0x40) fixed, 0b11 (0x30) for reserved fix, 0x0, first 4 bits for section length 31 | * 0x0d remaining 8 bits for section length 0x0d = 13 32 | * 0x00 first 8 bits of transport_stream_id fixed 33 | * 0x01 last 8 bits of transport_stream_id fixed 34 | * 0xc1 0b11 (0xC) reserved, 0b00000 (0x3E) version number, 0b1 current_next_indicator 1 means this PAT is valid 35 | * 0x00 section_number +1 for every section 36 | * 0x00 last_section_number 37 | * 38 | * // loop start 39 | * 0x00 first 8 bits of program number in PMT 40 | * 0x01 last 8 bits of program number in PMT 41 | * 0xf0 0b111 reserved 0b10000 first 5 bits of program number in PMT 42 | * 0x00 last 8 bits of program number in PMT 43 | * 44 | * // CRC 45 | * 0x2a 46 | * 0xb1 47 | * 0x04 48 | * 0xb2 49 | */ 50 | 51 | #include 52 | #include 53 | #include 54 | 55 | #include "S3_HLS_Pat.h" 56 | #include "S3_HLS_Return_Code.h" 57 | 58 | // #define S3_HLS_PAT_DEBUG 59 | 60 | #ifdef S3_HLS_PAT_DEBUG 61 | #define PAT_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 62 | #else 63 | #define PAT_DEBUG(x, ...) 64 | #endif 65 | 66 | #define S3_HLS_PAT_HEADER_LENGTH 188 67 | 68 | uint8_t const_pat[21] = { 0x47, 0x40, 0x00, 0x10, 0x00, 0x00, 0xb0, 0x0d, 69 | 0x00, 0x01, 0xc1, 0x00, 0x00, 0x00, 0x01, 0xf0, 70 | 0x00, 0x2a, 0xb1, 0x04, 0xb2}; 71 | 72 | int8_t m_pat_counter = 0; 73 | 74 | int32_t S3_HLS_H264_PAT_Write_To_Buffer(S3_HLS_BUFFER_CTX* buffer_ctx) { 75 | PAT_DEBUG("Writing PAT\n"); 76 | int32_t ret; 77 | 78 | const_pat[S3_HLS_TS_COUNTER_INDEX] &= 0xF0; 79 | const_pat[S3_HLS_TS_COUNTER_INDEX] |= (m_pat_counter & 0x0F); 80 | 81 | PAT_DEBUG("Put PAT to buffer\n"); 82 | ret = S3_HLS_Put_To_Buffer(buffer_ctx, const_pat, sizeof(const_pat)); 83 | if(0 > ret) 84 | return ret; 85 | 86 | ret = S3_HLS_Put_To_Buffer(buffer_ctx, const_fill_word, S3_HLS_PAT_HEADER_LENGTH - sizeof(const_pat)); 87 | if(0 > ret) 88 | return ret; 89 | 90 | m_pat_counter++; 91 | 92 | return S3_HLS_PAT_HEADER_LENGTH; 93 | } 94 | 95 | void S3_HLS_PAT_Reset_Counter() { 96 | m_pat_counter = 0; 97 | } -------------------------------------------------------------------------------- /demosite/static/js/3.d0d355a5.chunk.js: -------------------------------------------------------------------------------- 1 | (this["webpackJsonpip-camera-ui"]=this["webpackJsonpip-camera-ui"]||[]).push([[3],{220:function(t,e,n){"use strict";n.r(e),n.d(e,"getCLS",(function(){return v})),n.d(e,"getFCP",(function(){return y})),n.d(e,"getFID",(function(){return k})),n.d(e,"getLCP",(function(){return C})),n.d(e,"getTTFB",(function(){return P}));var i,a,r,o,u=function(t,e){return{name:t,value:void 0===e?-1:e,delta:0,entries:[],id:"v1-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},f=!1,s=function(t,e){f||"undefined"!=typeof InstallTrigger||(addEventListener("beforeunload",(function(){})),f=!0),addEventListener("visibilitychange",(function n(i){"hidden"===document.visibilityState&&(t(i),e&&removeEventListener("visibilitychange",n,!0))}),!0)},d=function(t){addEventListener("pageshow",(function(e){e.persisted&&t(e)}),!0)},m="function"==typeof WeakSet?new WeakSet:new Set,p=function(t,e,n){var i;return function(){e.value>=0&&(n||m.has(e)||"hidden"===document.visibilityState)&&(e.delta=e.value-(i||0),(e.delta||void 0===i)&&(i=e.value,t(e)))}},v=function(t,e){var n,i=u("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),n())},r=c("layout-shift",a);r&&(n=p(t,i,e),s((function(){r.takeRecords().map(a),n()})),d((function(){i=u("CLS",0),n=p(t,i,e)})))},l=-1,h=function(){return"hidden"===document.visibilityState?0:1/0},S=function(){s((function(t){var e=t.timeStamp;l=e}),!0)},g=function(){return l<0&&(l=h(),S(),d((function(){setTimeout((function(){l=h(),S()}),0)}))),{get timeStamp(){return l}}},y=function(t,e){var n,i=g(),a=u("FCP"),r=c("paint",(function(t){"first-contentful-paint"===t.name&&(r&&r.disconnect(),t.startTime=0&&a1e12?new Date:performance.now())-t.timeStamp;"pointerdown"==t.type?function(t,e){var n=function(){L(t,e),a()},i=function(){a()},a=function(){removeEventListener("pointerup",n,w),removeEventListener("pointercancel",i,w)};addEventListener("pointerup",n,w),addEventListener("pointercancel",i,w)}(e,t):L(e,t)}},F=function(t){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return t(e,b,w)}))},k=function(t,e){var n,r=g(),f=u("FID"),v=function(t){t.startTimediv{margin-bottom:10px}.search-tab-content .search{text-align:right}.App .ipc-header{height:40px}.App .breadcrumb{height:40px;top:40px}.App .ipc-body{min-height:calc(100vh - 30px)}.App .ipc-body .content{margin-top:80px}} 2 | /*# sourceMappingURL=main.3cb751cd.chunk.css.map */ -------------------------------------------------------------------------------- /S3_HLS_Pmt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | /* 20 | *. Format: 21 | * 22 | * TS Header 4 bytes 23 | * 0x47 sync 24 | * 0x50 payload_start + PID 0x1000 25 | * 0x00 pid 26 | * 0x30 contains payload data (0x10 always exists) and adaption field (0x20) 27 | * 0x00 adaption length field 28 | * 29 | *. PMT Header 30 | * 0x02 table_id 31 | * 0xb0 0b1 (0x80) - section _syntax_indicator, 0b0 (0x40) - zero bit, 0b11 (0x30) - reserved always 0b11, 0b0000 - frist 4 bits of section length 32 | * 0x17/12 remaining 8 bits of section length 33 | * 0x00 first 8 bits of program number 34 | * 0x01 last 8 bits of program number 35 | * 0xc1 0b11 (0xC0) - reserved always 0b11, version number - 0b00000 when pmt change add 1, current_next_indicator 0b1 (0x01) when 1 current program map is available 36 | * 0x00 0x00 section_number fix 37 | * 0x00 0x00 last_section_number fix 38 | * 0xe1 0b111 (0xe0) 0x1F (first 5 bits of PID that contains PCR, value is 0x01) 39 | * 0x00 0x00 last 8 bits for PID 40 | * 0xf0 reserved 0xf0, 4 bits for program_info_length (first 4 bits) 41 | * 0x00 last 8 bits of program_info_length 42 | * 0x1b stream_type, 0x1b for H264 video, 0x0f for ISO13818-7 (AAC LC?), 0x03 for ISO 11172-3 (mp3?) 43 | * 0xe1 0xe0 reserved 0x01 first 5 bits of PID 44 | * 0x00 remaining 8 bits of PID 45 | * 0xf0 0xf0 reserved 0x00 first 4 bits of es info length 46 | * 0x00 0x00 remaining 8 bits of es info length 47 | * 48 | * // audio part start 49 | * 0x0f stream_type 50 | * 0xe1 0xe0 reserved 0x01 first 5 bits of PID 51 | * 0x01 remaining 8 bits of PID 52 | * 0xf0 0xf0 reserved 0x00 first 4 bits of es info length 53 | * 0x00 0x00 remaining 8 bits of es info length 54 | * 55 | * // CRC start 56 | * 0x2f 57 | * 0x44 58 | * 0xb9 59 | * 0x9b 60 | */ 61 | 62 | 63 | #include 64 | #include 65 | #include 66 | 67 | #include "S3_HLS_Pmt.h" 68 | #include "S3_HLS_Buffer_Mgr.h" 69 | #include "S3_HLS_Return_Code.h" 70 | 71 | //#define S3_HLS_PMT_DEBUG 72 | 73 | #ifdef S3_HLS_PMT_DEBUG 74 | #define PMT_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 75 | #else 76 | #define PMT_DEBUG(x, ...) 77 | #endif 78 | 79 | #define S3_HLS_PMT_HEADER_LENGTH 188 80 | 81 | #define S3_HLS_AV_STRAM 82 | #ifdef S3_HLS_AV_STRAM 83 | // Video + Audio 84 | 85 | #define S3_HLS_AAC 86 | 87 | #ifdef S3_HLS_AAC // AAC 88 | uint8_t const_pmt[31] = { 0x47, 0x50, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x17, // length 89 | 0x00, 0x01, 0xc1, 0x00, 0x00, 0xe1, 0x00, 0xf0, // PCR PID = 0x0100, 90 | 0x00, 0x1b, 0xe1, 0x00, 0xf0, 0x00, 0x0f, 0xe1, // PID 0x100 is video, PID 0x101 is audio 91 | 0x01, 0xf0, 0x00, 0x2f, 0x44, 0xb9, 0x9b }; // last 4 bytes are crc 92 | #else // mp3? need generate crc 93 | uint8_t const_pmt[31] = { 0x47, 0x50, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x17, // length 94 | 0x00, 0x01, 0xc1, 0x00, 0x00, 0xe1, 0x00, 0xf0, // PCR PID = 0x0100, 95 | 0x00, 0x1b, 0xe1, 0x00, 0xf0, 0x00, 0x03, 0xe1, // PID 0x100 is video, PID 0x101 is audio 96 | 0x01, 0xf0, 0x00, 0x4e, 0x59, 0x3d, 0x1e }; // last 4 bytes are crc 97 | #endif 98 | 99 | #else 100 | // Video Only 101 | char const_pmt[26] = { 0x47, 0x50, 0x00, 0x10, 0x00, 0x02, 0xb0, 0x12, // length 102 | 0x00, 0x01, 0xc1, 0x00, 0x00, 0xe1, 0x00, 0xf0, // PCR PID = 0x0100, 103 | 0x00, 0x1b, 0xe1, 0x00, 0xf0, 0x00, 0x15, 0xbd, 104 | 0x4d, 0x56 }; // last 4 bytes are crc 105 | #endif 106 | 107 | int8_t m_pmt_counter = 0; 108 | 109 | int32_t S3_HLS_H264_PMT_Write_To_Buffer(S3_HLS_BUFFER_CTX* buffer_ctx) { 110 | PMT_DEBUG("Writing PMT!\n"); 111 | int32_t ret; 112 | 113 | const_pmt[S3_HLS_TS_COUNTER_INDEX] &= 0xF0; 114 | const_pmt[S3_HLS_TS_COUNTER_INDEX] |= (m_pmt_counter & 0x0F); 115 | 116 | PMT_DEBUG("Put PMT to buffer!\n"); 117 | ret = S3_HLS_Put_To_Buffer(buffer_ctx, const_pmt, sizeof(const_pmt)); 118 | if(0 > ret) 119 | return ret; 120 | 121 | ret = S3_HLS_Put_To_Buffer(buffer_ctx, const_fill_word, S3_HLS_PMT_HEADER_LENGTH - sizeof(const_pmt)); 122 | if(0 > ret) 123 | return ret; 124 | 125 | m_pmt_counter++; 126 | 127 | return S3_HLS_PMT_HEADER_LENGTH; 128 | } 129 | 130 | void S3_HLS_PMT_Reset_Counter() { 131 | m_pmt_counter = 0; 132 | } -------------------------------------------------------------------------------- /demosite/static/css/2.373bc5f8.chunk.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://node_modules/react-loader-spinner/dist/loader/css/CradleLoader.css","webpack://node_modules/react-loader-spinner/dist/loader/css/Plane.css","webpack://node_modules/react-loader-spinner/dist/loader/css/Triangle.css"],"names":[],"mappings":"AAAA,gCACE,iBAAkB,CAClB,UAAW,CACX,UAAW,CACX,SACF,CACA,8CAEE,mDACF,CACA,+CAEE,mDACF,CACA,+CAEE,mDACF,CACA,+CAEE,mDACF,CACA,+CAEE,mDACF,CACA,+CAEE,mDACF,CACA,+CAEE,mDACF,CACA,6BACE,UAAW,CACX,iBACF,CACA,iCACE,wBAAyB,CACzB,gBAAiB,CACjB,UAAW,CACX,SAAU,CACV,YAAa,CACb,iBAAkB,CAClB,kBACF,CACA,4DACE,kBACF,CACA,4DACE,kBACF,CAWA,kBACE,OAEE,iCACF,CACA,GAEE,0CACF,CACF,CAYA,kBACE,GAEE,0CACF,CACA,OAGE,iCACF,CACF,CAaA,sBACE,OACE,UAAW,CAEX,uBACF,CACA,GACE,YAAa,CAEb,6BACF,CACF,CAcA,sBACE,GACE,YAAa,CAEb,4BACF,CACA,OAEE,UAAW,CAEX,uBACF,CACF,CACA,8BAEE,qDACF,CACA,8BAEE,qDACF,CACA,+BAEE,yDACF,CACA,+BAEE,yDACF,CC/JA,oCACE,WAAY,CACZ,YAAa,CACb,4BAA6B,CAC7B,0CAA2C,CAC3C,kDACF,CAEA,2CAEE,+CAAgD,CAChD,uDACF,CAEA,uBACE,GACE,uBACF,CACF,CACA,uBACE,GACE,oCACF,CACA,IACE,2CACF,CACA,GACE,oCACF,CACF,CC7BA,8BAEU,wBACV,CAEA,sCACE,mBAAoB,CAEZ,0DACV,CAQA,gBACE,GACE,qBACF,CACF,CAOA,kBACE,GAEU,uBACV,CACF","file":"2.373bc5f8.chunk.css","sourcesContent":[".react-spinner-loader-swing div {\n border-radius: 50%;\n float: left;\n height: 1em;\n width: 1em;\n}\n.react-spinner-loader-swing div:nth-of-type(1) {\n background: -webkit-linear-gradient(left, #385c78 0%, #325774 100%);\n background: linear-gradient(to right, #385c78 0%, #325774 100%);\n}\n.react-spinner-loader-swing div:nth-of-type(2) {\n background: -webkit-linear-gradient(left, #325774 0%, #47536a 100%);\n background: linear-gradient(to right, #325774 0%, #47536a 100%);\n}\n.react-spinner-loader-swing div:nth-of-type(3) {\n background: -webkit-linear-gradient(left, #4a5369 0%, #6b4d59 100%);\n background: linear-gradient(to right, #4a5369 0%, #6b4d59 100%);\n}\n.react-spinner-loader-swing div:nth-of-type(4) {\n background: -webkit-linear-gradient(left, #744c55 0%, #954646 100%);\n background: linear-gradient(to right, #744c55 0%, #954646 100%);\n}\n.react-spinner-loader-swing div:nth-of-type(5) {\n background: -webkit-linear-gradient(left, #9c4543 0%, #bb4034 100%);\n background: linear-gradient(to right, #9c4543 0%, #bb4034 100%);\n}\n.react-spinner-loader-swing div:nth-of-type(6) {\n background: -webkit-linear-gradient(left, #c33f31 0%, #d83b27 100%);\n background: linear-gradient(to right, #c33f31 0%, #d83b27 100%);\n}\n.react-spinner-loader-swing div:nth-of-type(7) {\n background: -webkit-linear-gradient(left, #da3b26 0%, #db412c 100%);\n background: linear-gradient(to right, #da3b26 0%, #db412c 100%);\n}\n.react-spinner-loader-shadow {\n clear: left;\n padding-top: 1.5em;\n}\n.react-spinner-loader-shadow div {\n -webkit-filter: blur(1px);\n filter: blur(1px);\n float: left;\n width: 1em;\n height: .25em;\n border-radius: 50%;\n background: #e3dbd2;\n}\n.react-spinner-loader-shadow .react-spinner-loader-shadow-l {\n background: #d5d8d6;\n}\n.react-spinner-loader-shadow .react-spinner-loader-shadow-r {\n background: #eed3ca;\n}\n@-webkit-keyframes ball-l {\n 0%, 50% {\n -webkit-transform: rotate(0) translateX(0);\n transform: rotate(0) translateX(0);\n }\n 100% {\n -webkit-transform: rotate(50deg) translateX(-2.5em);\n transform: rotate(50deg) translateX(-2.5em);\n }\n}\n@keyframes ball-l {\n 0%, 50% {\n -webkit-transform: rotate(0) translate(0);\n transform: rotate(0) translateX(0);\n }\n 100% {\n -webkit-transform: rotate(50deg) translateX(-2.5em);\n transform: rotate(50deg) translateX(-2.5em);\n }\n}\n@-webkit-keyframes ball-r {\n 0% {\n -webkit-transform: rotate(-50deg) translateX(2.5em);\n transform: rotate(-50deg) translateX(2.5em);\n }\n 50%,\n 100% {\n -webkit-transform: rotate(0) translateX(0);\n transform: rotate(0) translateX(0);\n }\n}\n@keyframes ball-r {\n 0% {\n -webkit-transform: rotate(-50deg) translateX(2.5em);\n transform: rotate(-50deg) translateX(2.5em);\n }\n 50%,\n 100% {\n -webkit-transform: rotate(0) translateX(0);\n transform: rotate(0) translateX(0)\n }\n}\n@-webkit-keyframes shadow-l-n {\n 0%, 50% {\n opacity: .5;\n -webkit-transform: translateX(0);\n transform: translateX(0);\n }\n 100% {\n opacity: .125;\n -webkit-transform: translateX(-1.57em);\n transform: translateX(-1.75em);\n }\n}\n@keyframes shadow-l-n {\n 0%, 50% {\n opacity: .5;\n -webkit-transform: translateX(0);\n transform: translateX(0);\n }\n 100% {\n opacity: .125;\n -webkit-transform: translateX(-1.75);\n transform: translateX(-1.75em);\n }\n}\n@-webkit-keyframes shadow-r-n {\n 0% {\n opacity: .125;\n -webkit-transform: translateX(1.75em);\n transform: translateX(1.75em);\n }\n 50%,\n 100% {\n opacity: .5;\n -webkit-transform: translateX(0);\n transform: translateX(0);\n }\n}\n@keyframes shadow-r-n {\n 0% {\n opacity: .125;\n -webkit-transform: translateX(1.75em);\n transform: translateX(1.75em);\n }\n 50%,\n 100% {\n opacity: .5;\n -webkit-transform: translateX(0);\n transform: translateX(0);\n }\n}\n.react-spinner-loader-swing-l {\n -webkit-animation: ball-l .425s ease-in-out infinite alternate;\n animation: ball-l .425s ease-in-out infinite alternate;\n}\n.react-spinner-loader-swing-r {\n -webkit-animation: ball-r .425s ease-in-out infinite alternate;\n animation: ball-r .425s ease-in-out infinite alternate;\n}\n.react-spinner-loader-shadow-l {\n -webkit-animation: shadow-l-n .425s ease-in-out infinite alternate;\n animation: shadow-l-n .425s ease-in-out infinite alternate;\n}\n.react-spinner-loader-shadow-r {\n -webkit-animation: shadow-r-n .425s ease-in-out infinite alternate;\n animation: shadow-r-n .425s ease-in-out infinite alternate;\n}\n","\n.react-spinner-loader-svg-calLoader {\n width: 230px;\n height: 230px;\n transform-origin: 115px 115px;\n animation: 1.4s linear infinite loader-spin;\n -webkit-animation: 1.4s linear infinite loader-spin;\n}\n\n.react-spinner-loader-svg-cal-loader__path {\n\n animation: 1.4s ease-in-out infinite loader-path;\n -webkit-animation: 1.4s ease-in-out infinite loader-path;\n}\n\n@keyframes loader-spin {\n to {\n transform: rotate(360deg);\n }\n}\n@keyframes loader-path {\n 0% {\n stroke-dasharray: 0, 580, 0, 0, 0, 0, 0, 0, 0;\n }\n 50% {\n stroke-dasharray: 0, 450, 10, 30, 10, 30, 10, 30, 10;\n }\n 100% {\n stroke-dasharray: 0, 580, 0, 0, 0, 0, 0, 0, 0;\n }\n}\n","\n.react-spinner-loader-svg svg {\n -webkit-transform-origin: 50% 65%;\n transform-origin: 50% 65%;\n}\n\n.react-spinner-loader-svg svg polygon {\n stroke-dasharray: 17;\n -webkit-animation: dash 2.5s cubic-bezier(0.35, 0.04, 0.63, 0.95) infinite;\n animation: dash 2.5s cubic-bezier(0.35, 0.04, 0.63, 0.95) infinite;\n}\n\n@-webkit-keyframes dash {\n to {\n stroke-dashoffset: 136;\n }\n}\n\n@keyframes dash {\n to {\n stroke-dashoffset: 136;\n }\n}\n@-webkit-keyframes rotate {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@keyframes rotate {\n 100% {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n"]} -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # IPC-H264-HLS-C-SDK 2 | 3 | This is a sample code for IP Cameras (IPC for short) that use built-in MCU to generate TS format files and upload to S3. 4 | 5 | And the S3_Simple_Put part of this SDK can also be considered as sample for Signature V4 process when calling S3 APIs. 6 | 7 | With this SDK, IPC vendors don't need to pay for EC2 instances that receiving the video stream and only pay for the amount of storage they use to store the video. And can playback later with dynamically generated m3u8 file. 8 | 9 | The input parameters of this SDK inclucde AK/SK/Token for AWS S3 access, region name, bucket name and s3 object prefix (ususally the iot device certificate id). 10 | 11 | System requirement: 12 | IPC running Linux with H264 video encoding. 13 | SoC should have 3.5-4MB available memory when running @ 5Mbps data rate (Common data rate for 1080P video). 14 | Memory buffer can be adjusted according to the data rate when initialize the SDK. 15 | 16 | 3rd party library: (Already provided as submodule) 17 | OpenSSL 1.1.1 18 | Curl 7.70 19 | 20 | ## Design Overview 21 | 22 | Data flow is as following 23 | 24 | ``` 25 | 26 | IPC Encoding Module 27 | | 28 | | 29 | v 30 | H264 RAW Stream 31 | | 32 | | 33 | v 34 | S3_HLS_SDK Put Video/Audio Frame 35 | (Package to TS format) 36 | | 37 | | 38 | v 39 | S3_HLS_Buffer_Mgr (Cache) 40 | | 41 | | 42 | v 43 | Upload Queue 44 | | 45 | | 46 | v 47 | S3_HLS_S3_Put_Client 48 | | 49 | | 50 | v 51 | Amazon S3 (On Cloud) 52 | 53 | ``` 54 | 55 | ## How to Compile 56 | 57 | 1. Clone the current repository. 58 | 59 | ``` 60 | 61 | git clone https://github.com/aws-samples/ipc-h264-hls-c-sdk.git 62 | 63 | ``` 64 | 65 | 2. Ensure the 3rd OpenSSL project is working. 66 | 67 | ``` 68 | 69 | cd ipc-h264-hls-c-sdk/ 70 | git submodule init 71 | git submodule update 72 | 73 | ``` 74 | 75 | 3. Configure OpenSSL project. 76 | 77 | ``` 78 | 79 | cd 3rd/openssl/ 80 | ./Configure no-asm no-async no-egd --prefix=$PWD –-cross-compile-prefix= 81 | 82 | ``` 83 | 84 | Note: 85 | 86 | Change the "" to your cross compiler prefix. E.g.: mips-linux-gnu- etc. 87 | 88 | Change the "" to your target platform. E.g.: linux-x86_64 or linux-mips etc. And you may need to modify the generated Makefile on some platform and remove unsupported options. 89 | 90 | 4. Make OpenSSL project 91 | 92 | ``` 93 | 94 | make 95 | 96 | ``` 97 | 98 | Check the libcrypto.a & libssl.a files are generated in the openssl directory. 99 | 100 | 5. Configure Curl project 101 | 102 | ``` 103 | 104 | cd ../curl 105 | autoreconf -fi 106 | export LD_LIBRARY_PATH=../openssl 107 | export CROSS_COMPILE= 108 | export LDFLAGS="-L$PWD/../openssl/" 109 | ./configure ac_cv_func_RAND_egd=no --disable-shared --enable-static --with-ssl=$PWD/../openssl 110 | 111 | ``` 112 | 113 | 6. Compile Curl project 114 | 115 | ``` 116 | 117 | make 118 | 119 | ``` 120 | 121 | Check the libcurl.a file is generated at lib/.libs/ folder. 122 | 123 | 5. Compile IPC-H264-HLS-C-SDK 124 | 125 | ``` 126 | 127 | cd ../.. 128 | 129 | ``` 130 | 131 | Edit Makefile, add CROSS_COMPILE prefix if necessary. 132 | 133 | ``` 134 | 135 | CROSS_COMPILE= 136 | CC=$(CROSS_COMPILE)gcc 137 | LD=$(CROSS_COMPILE)ld 138 | AR=$(CROSS_COMPILE)ar 139 | 140 | ``` 141 | 142 | Compile IPC-H264-HLS-C-SDK. 143 | 144 | ``` 145 | 146 | make 147 | 148 | ``` 149 | 150 | 151 | Check the s3_hls.a file is generated in the directory. You need to link this library and corresponding libcrypto.a libssl.a library when creating your own application. 152 | 153 | ## IPC-H264-HLS-C-SDK usage sudo code example: 154 | 155 | 1. Initialize the system 156 | 157 | ``` 158 | 159 | #define BUFFER_SIZE 4*1024*1024 // 4MB 160 | if(S3_HLS_OK != S3_HLS_SDK_Initialize(BUFFER_SIZE, region_name, bucket_name, prefix, custom_endpoint_name) ) { 161 | return FAILED; 162 | } 163 | 164 | ``` 165 | 166 | 2. Set credential 167 | 168 | The credential used for SDK can be ak/sk generated using IAM console. The best practise is to use AWS IoT Device Managment. 169 | Use built in certificate to exchange temporary credential using Credentials Provider. 170 | Please refer to below blog for details: 171 | https://aws.amazon.com/blogs/security/how-to-eliminate-the-need-for-hardcoded-aws-credentials-in-devices-by-using-the-aws-iot-credentials-provider/ 172 | 173 | ``` 174 | 175 | if(S3_HLS_OK != S3_HLS_SDK_Set_Credential(argv[1], argv[2], argc >= 7 ? argv[6] : NULL)) { 176 | S3_HLS_SDK_Finalize(); 177 | return FAILED; 178 | } 179 | 180 | 181 | ``` 182 | 183 | During execution, user can call this function to replace credentials used to upload video clips. 184 | 185 | 3. Optionally user can specify tags that added to uploaded video clips 186 | 187 | ``` 188 | 189 | S3_HLS_SDK_Set_Tag("key1=value1"); 190 | 191 | ``` 192 | 193 | 4. Start upload thread for upload video clips to S3 194 | 195 | ``` 196 | 197 | S3_HLS_SDK_Start_Upload(); 198 | 199 | ``` 200 | 201 | 5. In the main thread of processing frames 202 | 203 | ``` 204 | 205 | // Main thread for processing frames: 206 | while(!exit) { 207 | // Get video stream from IPC 208 | int nr_pack = stream->packCount; 209 | 210 | S3_HLS_FRAME_PACK s3_frame_pack; 211 | s3_frame_pack.item_count = nr_pack; 212 | 213 | for(int i=0; i < nr_pack; i++) { 214 | IMPEncoderPack *pack = &stream->pack[i]; 215 | // use timestamp generated by encoder 216 | s3_frame_pack.items[i].timestamp = pack->timestamp; 217 | if(pack->length){ 218 | uint32_t remSize = stream->streamSize - pack->offset; 219 | if(remSize < pack->length){ // IPC buffer acrossed internal ring buffer boundary 220 | s3_frame_pack.items[i].first_part_start = (void *)(stream->virAddr + pack->offset); 221 | s3_frame_pack.items[i].first_part_length = remSize; 222 | 223 | s3_frame_pack.items[i].second_part_start = (void *)stream->virAddr; 224 | s3_frame_pack.items[i].second_part_length = pack->length - remSize; 225 | }else { // IPC buffer does not across internal ring buffer boundary 226 | s3_frame_pack.items[i].first_part_start = (void *)(stream->virAddr + pack->offset); 227 | s3_frame_pack.items[i].first_part_length = pack->length; 228 | 229 | s3_frame_pack.items[i].second_part_start = NULL; 230 | s3_frame_pack.items[i].second_part_length = 0; 231 | } 232 | } 233 | 234 | S3_HLS_SDK_Put_Video_Frame(&s3_frame_pack); 235 | } 236 | 237 | 238 | ``` 239 | 240 | 5. When exit the program, do some clean up tasks 241 | 242 | ``` 243 | 244 | S3_HLS_SDK_Finalize(); 245 | 246 | ``` 247 | 248 | For using IoT Core to get AK/SK/Token, please refer to below link: 249 | https://docs.aws.amazon.com/iot/latest/developerguide/authorizing-direct-aws.html 250 | 251 | ## Security 252 | 253 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 254 | 255 | ## License 256 | 257 | This library is licensed under the MIT-0 License. See the LICENSE file. 258 | 259 | -------------------------------------------------------------------------------- /S3_HLS_Queue.c: -------------------------------------------------------------------------------- 1 | #include "stdlib.h" 2 | #include "stdio.h" 3 | #include "S3_HLS_Queue.h" 4 | #include "S3_HLS_Return_Code.h" 5 | 6 | #define S3_HLS_QUEUE_DEBUG 7 | 8 | #ifdef S3_HLS_QUEUE_DEBUG 9 | #define QUEUE_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 10 | #else 11 | #define QUEUE_DEBUG(x, ...) 12 | #endif 13 | 14 | S3_HLS_QUEUE_CTX* S3_HLS_Initialize_Queue() { 15 | QUEUE_DEBUG("Initializing Queue!\n"); 16 | S3_HLS_QUEUE_CTX* ret = NULL; 17 | 18 | ret = (S3_HLS_QUEUE_CTX*)malloc(sizeof(S3_HLS_QUEUE_CTX)); 19 | if(NULL == ret) { 20 | QUEUE_DEBUG("[Init]Failed to allocate queue context!\n"); 21 | return ret; 22 | } 23 | 24 | ret->queue_pos = 0; 25 | ret->queue_length = 0; 26 | 27 | pthread_mutexattr_t mattr; 28 | if(0 != pthread_mutexattr_init(&mattr)) { 29 | QUEUE_DEBUG("[Init]Failed to initialize queue lock attribute!\n"); 30 | free(ret); 31 | return NULL; 32 | } 33 | 34 | int32_t protocol; 35 | if(0 != pthread_mutexattr_getprotocol(&mattr, &protocol)) { 36 | QUEUE_DEBUG("[Init]Failed to get queue lock protocol!\n"); 37 | free(ret); 38 | return NULL; 39 | } 40 | 41 | QUEUE_DEBUG("[Init]Queue Protocol: %d\n", protocol); 42 | 43 | if(0 != pthread_mutex_init(&ret->s3_hls_queue_lock, &mattr)) { 44 | QUEUE_DEBUG("[Init]Failed to initialize queue lock!\n"); 45 | free(ret); 46 | return NULL; 47 | } 48 | 49 | for(uint32_t i = 0; i < S3_HLS_MAX_PARTS_IN_BUFFER; i++) { 50 | ret->queue[i].first_part_start = NULL; 51 | ret->queue[i].second_part_start = NULL; 52 | 53 | ret->queue[i].first_part_length = 0; 54 | ret->queue[i].second_part_length = 0; 55 | 56 | ret->queue[i].timestamp = 0; 57 | } 58 | 59 | return ret; 60 | } 61 | 62 | int32_t S3_HLS_Add_To_Queue(S3_HLS_QUEUE_CTX* ctx, uint8_t* first_part, uint32_t first_length, uint8_t* second_part, uint32_t second_length, time_t timestamp) { 63 | if(NULL == ctx) { 64 | QUEUE_DEBUG("[Add]Invalid Queue Context!\n"); 65 | return S3_HLS_INVALID_PARAMETER; 66 | } 67 | 68 | QUEUE_DEBUG("[Add]Locking queue! %lu\n", pthread_self()); 69 | int32_t ret = pthread_mutex_lock(&ctx->s3_hls_queue_lock); 70 | if(0 != ret) { 71 | QUEUE_DEBUG("[Add]Failed to lock queue lock! %d\n", ret); 72 | return ret; 73 | } 74 | 75 | QUEUE_DEBUG("Current queue length: %d\n", ctx->queue_length); 76 | if(ctx->queue_length == S3_HLS_MAX_PARTS_IN_BUFFER) { 77 | QUEUE_DEBUG("[Add]Queue is full!\n"); 78 | ret = pthread_mutex_unlock(&ctx->s3_hls_queue_lock); 79 | if(0 != ret) { 80 | QUEUE_DEBUG("[Add]Unlock queue failed! %d\n", ret); 81 | } 82 | return S3_HLS_QUEUE_FULL; // queue is full 83 | } 84 | 85 | uint8_t current_pos = ctx->queue_pos + ctx->queue_length; 86 | if(current_pos >= S3_HLS_MAX_PARTS_IN_BUFFER) 87 | current_pos -= S3_HLS_MAX_PARTS_IN_BUFFER; 88 | 89 | ctx->queue[current_pos].first_part_start = first_part; 90 | ctx->queue[current_pos].first_part_length = first_length; 91 | ctx->queue[current_pos].second_part_start = second_part; 92 | ctx->queue[current_pos].second_part_length = second_length; 93 | ctx->queue[current_pos].timestamp = timestamp; 94 | 95 | QUEUE_DEBUG("Before increase length: %d\n", ctx->queue_length); 96 | 97 | ctx->queue_length++; 98 | 99 | QUEUE_DEBUG("Added to queue! length: %d\n", ctx->queue_length); 100 | 101 | QUEUE_DEBUG("[Add]Unlocking queue!%lu\n", pthread_self()); 102 | ret = pthread_mutex_unlock(&ctx->s3_hls_queue_lock); 103 | if(0 != ret) { 104 | QUEUE_DEBUG("[Add]Failed to unlock queue lock! %d\n", ret); 105 | return ret; 106 | } 107 | 108 | return S3_HLS_OK; 109 | } 110 | 111 | int32_t S3_HLS_Release_Queue(S3_HLS_QUEUE_CTX* ctx) { 112 | if(NULL == ctx) { 113 | QUEUE_DEBUG("[Release]Invalid Queue Context!\n"); 114 | return S3_HLS_INVALID_PARAMETER; 115 | } 116 | 117 | QUEUE_DEBUG("[Release]Locking queue!\n"); 118 | int32_t ret = pthread_mutex_lock(&ctx->s3_hls_queue_lock); 119 | if(0 != ret) { 120 | // unknown error 121 | QUEUE_DEBUG("[Release]Get Queue Lock Failed! %d\n", ret); 122 | return ret; 123 | } 124 | 125 | if(ctx->queue_length > 0) { 126 | ctx->queue_pos ++; 127 | ctx->queue_length--; 128 | QUEUE_DEBUG("Released queue! length: %d\n", ctx->queue_length); 129 | 130 | if(S3_HLS_MAX_PARTS_IN_BUFFER == ctx->queue_pos) 131 | ctx->queue_pos = 0; 132 | } else { 133 | QUEUE_DEBUG("Queue is empty cannot release!\n"); 134 | } 135 | 136 | QUEUE_DEBUG("[Release]Unlocking queue!\n"); 137 | ret = pthread_mutex_unlock(&ctx->s3_hls_queue_lock); 138 | if(0 != ret) { 139 | // unknown error 140 | QUEUE_DEBUG("[Release]Get Queue Unlock Failed! %d\n", ret); 141 | return ret; 142 | } 143 | return S3_HLS_OK; 144 | } 145 | 146 | int32_t S3_HLS_Finalize_Queue(S3_HLS_QUEUE_CTX* ctx) { 147 | if(NULL == ctx) { 148 | return S3_HLS_INVALID_PARAMETER; 149 | } 150 | 151 | int32_t ret = pthread_mutex_destroy(&ctx->s3_hls_queue_lock); 152 | if(0 != ret) { 153 | QUEUE_DEBUG("Failed to destroy queue lock!\n"); 154 | } 155 | 156 | free(ctx); 157 | 158 | return ret; 159 | } 160 | 161 | int32_t S3_HLS_Get_Item_From_Queue(S3_HLS_QUEUE_CTX* ctx, S3_HLS_BUFFER_PART_CTX* buffer_ctx) { 162 | QUEUE_DEBUG("Get Item From Queue!\n"); 163 | if(NULL == ctx || NULL == buffer_ctx) { 164 | QUEUE_DEBUG("Invalid Queue Context!\n"); 165 | return S3_HLS_INVALID_PARAMETER; 166 | } 167 | 168 | QUEUE_DEBUG("[Get]Locking queue!\n"); 169 | int32_t ret = pthread_mutex_lock(&ctx->s3_hls_queue_lock); 170 | if(0 != ret) { 171 | QUEUE_DEBUG("[Get]Failed to lock queue lock! %d\n", ret); 172 | return ret; 173 | } 174 | 175 | 176 | if(0 == ctx->queue_length) { 177 | QUEUE_DEBUG("[Get]Queue is Empty!\n"); 178 | ret = pthread_mutex_unlock(&ctx->s3_hls_queue_lock); 179 | if(0 != ret) { 180 | QUEUE_DEBUG("[Get]Unlock queue failed! %d\n", ret); 181 | } 182 | buffer_ctx->first_part_start = NULL; 183 | buffer_ctx->first_part_length = 0; 184 | buffer_ctx->second_part_start = NULL; 185 | buffer_ctx->second_part_length = 0; 186 | buffer_ctx->timestamp = 0; 187 | return ret; // queue is full 188 | } 189 | 190 | buffer_ctx->first_part_start = ctx->queue[ctx->queue_pos].first_part_start; 191 | buffer_ctx->first_part_length = ctx->queue[ctx->queue_pos].first_part_length; 192 | buffer_ctx->second_part_start = ctx->queue[ctx->queue_pos].second_part_start; 193 | buffer_ctx->second_part_length = ctx->queue[ctx->queue_pos].second_part_length; 194 | buffer_ctx->timestamp = ctx->queue[ctx->queue_pos].timestamp; 195 | 196 | QUEUE_DEBUG("[Get]Unlocking queue!\n"); 197 | ret = pthread_mutex_unlock(&ctx->s3_hls_queue_lock); 198 | if(0 != ret) { 199 | QUEUE_DEBUG("[Get]Failed to unlock queue lock! %d\n", ret); 200 | return ret; 201 | } 202 | 203 | return S3_HLS_OK; 204 | } 205 | -------------------------------------------------------------------------------- /S3_HLS_Buffer_Mgr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | #include "S3_HLS_Buffer_Mgr.h" 7 | #include "S3_HLS_Return_Code.h" 8 | 9 | #define S3_HLS_BUFFER_FLUSH_CLEAR_DEBUG 10 | 11 | #ifdef S3_HLS_BUFFER_FLUSH_CLEAR_DEBUG 12 | #define BUFFER_FLUSH_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 13 | #else 14 | #define BUFFER_FLUSH_DEBUG(x, ...) 15 | #endif 16 | 17 | //#define S3_HLS_BUFFER_DEBUG 18 | 19 | #ifdef S3_HLS_BUFFER_DEBUG 20 | #define BUFFER_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 21 | #else 22 | #define BUFFER_DEBUG(x, ...) 23 | #endif 24 | 25 | /* 26 | * Buffer manager is a central managememnt of video and audio buffer that is cached for sending to S3 27 | * Initialize will allocate memory buffer for given size 28 | */ 29 | S3_HLS_BUFFER_CTX* S3_HLS_Initialize_Buffer(uint32_t buffer_size, BUFFER_CALL_BACK function_pointer) { 30 | BUFFER_DEBUG("Initializing Buffer!\n"); 31 | S3_HLS_BUFFER_CTX* ret = NULL; 32 | ret = (S3_HLS_BUFFER_CTX*)malloc(sizeof(S3_HLS_BUFFER_CTX)); 33 | if(NULL == ret) { 34 | BUFFER_DEBUG("Failed to allocate buffer context!\n"); 35 | return ret; 36 | } 37 | 38 | ret->buffer_start = (uint8_t*)malloc(buffer_size); 39 | if(NULL == ret->buffer_start) { 40 | BUFFER_DEBUG("Failed to allocate buffer!\n"); 41 | free(ret); 42 | return NULL; 43 | } 44 | 45 | if(0 != pthread_mutex_init(&ret->buffer_lock, NULL)) { 46 | BUFFER_DEBUG("Failed to initialize buffer lock!\n"); 47 | free(ret->buffer_start); 48 | free(ret); 49 | return NULL; 50 | } 51 | 52 | ret->total_length = buffer_size; 53 | 54 | ret->used_start = ret->buffer_start; 55 | ret->used_length = 0; 56 | 57 | ret->last_flush = ret->buffer_start; 58 | 59 | BUFFER_DEBUG("Callback function address %ld", function_pointer); 60 | ret->call_back = function_pointer; 61 | 62 | return ret; 63 | } 64 | 65 | /* 66 | * Buffer manager is a central managememnt of video and audio buffer that is cached for sending to S3 67 | * Initialize will allocate memory buffer for given size 68 | */ 69 | void S3_HLS_Finalize_Buffer(S3_HLS_BUFFER_CTX* ctx) { 70 | pthread_mutex_destroy(&ctx->buffer_lock); 71 | 72 | free(ctx->buffer_start); 73 | free(ctx); 74 | } 75 | 76 | /* 77 | * Flush buffer will switch the partition of buffer that pending send out and 78 | * buffer that is currently put data into 79 | */ 80 | int32_t S3_HLS_Flush_Buffer(S3_HLS_BUFFER_CTX* ctx) { 81 | BUFFER_FLUSH_DEBUG("Flushing buffer!\n"); 82 | if(NULL == ctx) 83 | return S3_HLS_INVALID_PARAMETER; 84 | 85 | uint8_t* cur_pos = ctx->used_start + ctx->used_length; 86 | if(NULL == ctx->last_flush) { 87 | BUFFER_FLUSH_DEBUG("Invalid last flush time!\n"); 88 | return S3_HLS_INVALID_PARAMETER; // valid ctx will contain last_flush 89 | } 90 | 91 | if(0 == ctx->used_length) { 92 | BUFFER_FLUSH_DEBUG("Buffer is empty!\n"); 93 | time(&ctx->last_flush_timestamp); 94 | return S3_HLS_OK; 95 | } 96 | 97 | if(ctx->last_flush != cur_pos) { // avoid duplicate flush especially when buffer is full 98 | if(NULL != ctx->call_back) { 99 | BUFFER_FLUSH_DEBUG("Calling callback function!\n"); 100 | S3_HLS_BUFFER_PART_CTX part_ctx; 101 | if(cur_pos >= ctx->buffer_start + ctx->total_length) 102 | cur_pos -= ctx->total_length; 103 | 104 | if(ctx->last_flush < cur_pos) { 105 | part_ctx.first_part_start = ctx->last_flush; 106 | part_ctx.first_part_length = cur_pos - ctx->last_flush; 107 | 108 | part_ctx.second_part_start = NULL; 109 | part_ctx.second_part_length = 0; 110 | } else { // acrossed ring buffer boundary 111 | part_ctx.first_part_start = ctx->last_flush; 112 | part_ctx.first_part_length = ctx->buffer_start + ctx->total_length - ctx->last_flush; 113 | 114 | part_ctx.second_part_start = ctx->buffer_start; 115 | part_ctx.second_part_length = cur_pos - ctx->buffer_start; 116 | } 117 | 118 | part_ctx.timestamp = ctx->last_flush_timestamp; 119 | 120 | ctx->call_back(&part_ctx); 121 | printf("Flush Buffer %p, %p, %d, %p, %d\n", ctx->last_flush, part_ctx.first_part_start, part_ctx.first_part_length, part_ctx.second_part_start, part_ctx.second_part_length); 122 | } 123 | 124 | ctx->last_flush = cur_pos; 125 | time(&ctx->last_flush_timestamp); 126 | } 127 | 128 | return S3_HLS_OK; 129 | } 130 | 131 | /* 132 | * Clear buffer will release buffer that provided by flush buffer 133 | * After clear the buffer, it can be reused by other input 134 | */ 135 | int32_t S3_HLS_Clear_Buffer(S3_HLS_BUFFER_CTX* buffer_ctx, S3_HLS_BUFFER_PART_CTX* part_ctx) { 136 | BUFFER_FLUSH_DEBUG("Clear Buffer!\n"); 137 | if(NULL == buffer_ctx || NULL == part_ctx) 138 | return S3_HLS_INVALID_PARAMETER; 139 | 140 | if(NULL == part_ctx->second_part_start && 0 < part_ctx->second_part_length) 141 | return S3_HLS_INVALID_PARAMETER; 142 | 143 | // Only support clear buffer in sequence, not support clear buffer in middle of used buffer 144 | printf("Clear Buffer %p, %d, %p, %d\n", part_ctx->first_part_start, part_ctx->first_part_length, part_ctx->second_part_start, part_ctx->second_part_length); 145 | if(buffer_ctx->used_start != part_ctx->first_part_start) { 146 | printf("Clear buffer not match start! %p, %p\n", buffer_ctx->used_start, part_ctx->first_part_start); 147 | } 148 | 149 | uint8_t* next_start = (NULL == part_ctx->second_part_start) ? (part_ctx->first_part_start + part_ctx->first_part_length) : (part_ctx->second_part_start + part_ctx->second_part_length); 150 | if(next_start > buffer_ctx->used_start) { 151 | buffer_ctx->used_length -= (next_start - buffer_ctx->used_start); 152 | } else if(next_start < buffer_ctx->used_start) { 153 | buffer_ctx->used_length -= buffer_ctx->total_length - (buffer_ctx->used_start - next_start); 154 | } 155 | 156 | buffer_ctx->used_start = next_start; 157 | /* 158 | uint32_t release_length = (part_ctx->first_part_length + part_ctx->second_part_length); 159 | 160 | buffer_ctx->used_length -= release_length; 161 | buffer_ctx->used_start += release_length; 162 | */ 163 | printf("Buffer Info: %p, %u, %p, %d\n", buffer_ctx->used_start, buffer_ctx->used_length, buffer_ctx->buffer_start, buffer_ctx->total_length); 164 | if(buffer_ctx->used_start >= buffer_ctx->buffer_start + buffer_ctx->total_length) { 165 | buffer_ctx->used_start -= buffer_ctx->total_length; 166 | } 167 | printf("New Buffer Start: %p\n", buffer_ctx->used_start); 168 | 169 | return S3_HLS_OK; 170 | } 171 | 172 | /* 173 | * Put data into buffer 174 | */ 175 | int32_t S3_HLS_Put_To_Buffer(S3_HLS_BUFFER_CTX* ctx, uint8_t* data, uint32_t length) { 176 | BUFFER_DEBUG("Putting Buffer!\n"); 177 | if(NULL == ctx) { 178 | BUFFER_DEBUG("Invalid Buffer Context!\n"); 179 | return S3_HLS_INVALID_PARAMETER; 180 | } 181 | 182 | if(NULL == data && 0 < length) { 183 | BUFFER_DEBUG("Input data address is NULL, but length is not 0\n"); 184 | return S3_HLS_INVALID_PARAMETER; 185 | } 186 | 187 | // lock is handled outside put if necessary 188 | if(ctx->total_length < ctx->used_length + length) { 189 | BUFFER_DEBUG("Buffer is full, currently used %d, new data %d\n", ctx->used_length, length); 190 | return S3_HLS_BUFFER_OVERFLOW; 191 | } 192 | 193 | BUFFER_DEBUG("Copy Buffer!\n"); 194 | uint8_t* buffer_end = ctx->buffer_start + ctx->total_length; 195 | uint8_t* current = ctx->used_start + ctx->used_length; 196 | if(current >= buffer_end) 197 | current -= ctx->total_length; 198 | 199 | if(buffer_end - current < length) { 200 | // acrossed ring buffer boundary 201 | memcpy(current, data, buffer_end - current); 202 | memcpy(ctx->buffer_start, data + (buffer_end - current), length - (buffer_end - current)); 203 | } else { 204 | memcpy(current, data, length); 205 | } 206 | 207 | ctx->used_length += length; 208 | 209 | return length; 210 | } 211 | 212 | int32_t S3_HLS_Lock_Buffer(S3_HLS_BUFFER_CTX* ctx) { 213 | if(NULL == ctx) { 214 | return S3_HLS_INVALID_PARAMETER; 215 | } 216 | 217 | return pthread_mutex_lock(&ctx->buffer_lock); 218 | } 219 | 220 | int32_t S3_HLS_Unlock_Buffer(S3_HLS_BUFFER_CTX* ctx) { 221 | if(NULL == ctx) { 222 | return S3_HLS_INVALID_PARAMETER; 223 | } 224 | 225 | return pthread_mutex_unlock(&ctx->buffer_lock); 226 | } 227 | 228 | -------------------------------------------------------------------------------- /demosite/static/js/3.d0d355a5.chunk.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../node_modules/web-vitals/dist/web-vitals.js"],"names":["t","e","n","i","a","name","value","delta","entries","id","concat","Date","now","Math","floor","random","r","PerformanceObserver","supportedEntryTypes","includes","getEntries","map","observe","type","buffered","o","c","InstallTrigger","addEventListener","document","visibilityState","removeEventListener","u","persisted","f","WeakSet","Set","s","has","m","hadRecentInput","push","takeRecords","d","v","p","timeStamp","l","setTimeout","S","disconnect","startTime","add","requestAnimationFrame","performance","h","passive","capture","y","g","L","E","entryType","target","cancelable","processingStart","forEach","w","T","b","once","F","getEntriesByType","timing","max","navigationStart","responseStart","readyState"],"mappings":"oHAAA,+MAAIA,EAAEC,EAAEC,EAAEC,EAAEC,EAAE,SAASJ,EAAEC,GAAG,MAAM,CAACI,KAAKL,EAAEM,WAAM,IAASL,GAAG,EAAEA,EAAEM,MAAM,EAAEC,QAAQ,GAAGC,GAAG,MAAMC,OAAOC,KAAKC,MAAM,KAAKF,OAAOG,KAAKC,MAAM,cAAcD,KAAKE,UAAU,QAAQC,EAAE,SAAShB,EAAEC,GAAG,IAAI,GAAGgB,oBAAoBC,oBAAoBC,SAASnB,GAAG,CAAC,IAAIE,EAAE,IAAIe,qBAAqB,SAASjB,GAAG,OAAOA,EAAEoB,aAAaC,IAAIpB,MAAM,OAAOC,EAAEoB,QAAQ,CAACC,KAAKvB,EAAEwB,UAAS,IAAKtB,GAAG,MAAMF,MAAMyB,GAAE,EAAGC,EAAE,SAAS1B,EAAEC,GAAGwB,GAAG,oBAAoBE,iBAAiBC,iBAAiB,gBAAgB,eAAeH,GAAE,GAAIG,iBAAiB,oBAAoB,SAAS1B,EAAEC,GAAG,WAAW0B,SAASC,kBAAkB9B,EAAEG,GAAGF,GAAG8B,oBAAoB,mBAAmB7B,GAAE,OAAO,IAAK8B,EAAE,SAAShC,GAAG4B,iBAAiB,YAAY,SAAS3B,GAAGA,EAAEgC,WAAWjC,EAAEC,MAAK,IAAKiC,EAAE,mBAAmBC,QAAQ,IAAIA,QAAQ,IAAIC,IAAIC,EAAE,SAASrC,EAAEC,EAAEC,GAAG,IAAIC,EAAE,OAAO,WAAWF,EAAEK,OAAO,IAAIJ,GAAGgC,EAAEI,IAAIrC,IAAI,WAAW4B,SAASC,mBAAmB7B,EAAEM,MAAMN,EAAEK,OAAOH,GAAG,IAAIF,EAAEM,YAAO,IAASJ,KAAKA,EAAEF,EAAEK,MAAMN,EAAEC,OAAOsC,EAAE,SAASvC,EAAEC,GAAG,IAAIC,EAAEC,EAAEC,EAAE,MAAM,GAAGqB,EAAE,SAASzB,GAAGA,EAAEwC,iBAAiBrC,EAAEG,OAAON,EAAEM,MAAMH,EAAEK,QAAQiC,KAAKzC,GAAGE,MAAMgC,EAAElB,EAAE,eAAeS,GAAGS,IAAIhC,EAAEmC,EAAErC,EAAEG,EAAEF,GAAGyB,GAAG,WAAWQ,EAAEQ,cAAcrB,IAAII,GAAGvB,OAAO8B,GAAG,WAAW7B,EAAEC,EAAE,MAAM,GAAGF,EAAEmC,EAAErC,EAAEG,EAAEF,QAAQ0C,GAAG,EAAEC,EAAE,WAAW,MAAM,WAAWf,SAASC,gBAAgB,EAAE,KAAKe,EAAE,WAAWnB,GAAG,SAAS1B,GAAG,IAAIC,EAAED,EAAE8C,UAAUH,EAAE1C,KAAI,IAAK8C,EAAE,WAAW,OAAOJ,EAAE,IAAIA,EAAEC,IAAIC,IAAIb,GAAG,WAAWgB,YAAY,WAAWL,EAAEC,IAAIC,MAAM,OAAO,CAAC,gBAAgB,OAAOF,KAAKM,EAAE,SAASjD,EAAEC,GAAG,IAAIC,EAAEC,EAAE4C,IAAItB,EAAErB,EAAE,OAAOsB,EAAEV,EAAE,SAAS,SAAShB,GAAG,2BAA2BA,EAAEK,OAAOqB,GAAGA,EAAEwB,aAAalD,EAAEmD,UAAUhD,EAAE2C,YAAYrB,EAAEnB,MAAMN,EAAEmD,UAAU1B,EAAEjB,QAAQiC,KAAKzC,GAAGkC,EAAEkB,IAAI3B,GAAGvB,SAASwB,IAAIxB,EAAEmC,EAAErC,EAAEyB,EAAExB,GAAG+B,GAAG,SAAS7B,GAAGsB,EAAErB,EAAE,OAAOF,EAAEmC,EAAErC,EAAEyB,EAAExB,GAAGoD,uBAAuB,WAAWA,uBAAuB,WAAW5B,EAAEnB,MAAMgD,YAAY1C,MAAMT,EAAE2C,UAAUZ,EAAEkB,IAAI3B,GAAGvB,eAAeqD,EAAE,CAACC,SAAQ,EAAGC,SAAQ,GAAIC,EAAE,IAAI/C,KAAKgD,EAAE,SAASxD,EAAEC,GAAGJ,IAAIA,EAAEI,EAAEH,EAAEE,EAAED,EAAE,IAAIS,KAAKiD,EAAE7B,qBAAqB8B,MAAMA,EAAE,WAAW,GAAG5D,GAAG,GAAGA,EAAEC,EAAEwD,EAAE,CAAC,IAAItD,EAAE,CAAC0D,UAAU,cAAczD,KAAKL,EAAEuB,KAAKwC,OAAO/D,EAAE+D,OAAOC,WAAWhE,EAAEgE,WAAWb,UAAUnD,EAAE8C,UAAUmB,gBAAgBjE,EAAE8C,UAAU7C,GAAGE,EAAE+D,SAAS,SAASlE,GAAGA,EAAEI,MAAMD,EAAE,KAAKgE,EAAE,SAASnE,GAAG,GAAGA,EAAEgE,WAAW,CAAC,IAAI/D,GAAGD,EAAE8C,UAAU,KAAK,IAAInC,KAAK2C,YAAY1C,OAAOZ,EAAE8C,UAAU,eAAe9C,EAAEuB,KAAK,SAASvB,EAAEC,GAAG,IAAIC,EAAE,WAAWyD,EAAE3D,EAAEC,GAAGG,KAAKD,EAAE,WAAWC,KAAKA,EAAE,WAAW2B,oBAAoB,YAAY7B,EAAEqD,GAAGxB,oBAAoB,gBAAgB5B,EAAEoD,IAAI3B,iBAAiB,YAAY1B,EAAEqD,GAAG3B,iBAAiB,gBAAgBzB,EAAEoD,GAA9N,CAAkOtD,EAAED,GAAG2D,EAAE1D,EAAED,KAAK4D,EAAE,SAAS5D,GAAG,CAAC,YAAY,UAAU,aAAa,eAAekE,SAAS,SAASjE,GAAG,OAAOD,EAAEC,EAAEkE,EAAEZ,OAAOa,EAAE,SAASlE,EAAEuB,GAAG,IAAIc,EAAEI,EAAEI,IAAIH,EAAExC,EAAE,OAAOyC,EAAE,SAAS7C,GAAGA,EAAEmD,UAAUR,EAAEG,YAAYF,EAAEtC,MAAMN,EAAEiE,gBAAgBjE,EAAEmD,UAAUP,EAAEpC,QAAQiC,KAAKzC,GAAGkC,EAAEkB,IAAIR,GAAGL,MAAMU,EAAEjC,EAAE,cAAc6B,GAAGN,EAAEF,EAAEnC,EAAE0C,EAAEnB,GAAGwB,GAAGvB,GAAG,WAAWuB,EAAEP,cAAcrB,IAAIwB,GAAGI,EAAEC,gBAAe,GAAID,GAAGjB,GAAG,WAAW,IAAIhB,EAAE4B,EAAExC,EAAE,OAAOmC,EAAEF,EAAEnC,EAAE0C,EAAEnB,GAAGtB,EAAE,GAAGF,GAAG,EAAED,EAAE,KAAK4D,EAAEhC,kBAAkBZ,EAAE6B,EAAE1C,EAAEsC,KAAKzB,GAAG6C,QAAQQ,EAAE,SAASrE,EAAEC,GAAG,IAAIC,EAAEC,EAAE4C,IAAItB,EAAErB,EAAE,OAAOmC,EAAE,SAASvC,GAAG,IAAIC,EAAED,EAAEmD,UAAUlD,EAAEE,EAAE2C,YAAYrB,EAAEnB,MAAML,EAAEwB,EAAEjB,QAAQiC,KAAKzC,IAAIE,KAAKyC,EAAE3B,EAAE,2BAA2BuB,GAAG,GAAGI,EAAE,CAACzC,EAAEmC,EAAErC,EAAEyB,EAAExB,GAAG,IAAI2C,EAAE,WAAWV,EAAEI,IAAIb,KAAKkB,EAAED,cAAcrB,IAAIkB,GAAGI,EAAEO,aAAahB,EAAEkB,IAAI3B,GAAGvB,MAAM,CAAC,UAAU,SAASgE,SAAS,SAASlE,GAAG4B,iBAAiB5B,EAAE4C,EAAE,CAAC0B,MAAK,EAAGb,SAAQ,OAAQ/B,EAAEkB,GAAE,GAAIZ,GAAG,SAAS7B,GAAGsB,EAAErB,EAAE,OAAOF,EAAEmC,EAAErC,EAAEyB,EAAExB,GAAGoD,uBAAuB,WAAWA,uBAAuB,WAAW5B,EAAEnB,MAAMgD,YAAY1C,MAAMT,EAAE2C,UAAUZ,EAAEkB,IAAI3B,GAAGvB,eAAeqE,EAAE,SAASvE,GAAG,IAAIC,EAAEC,EAAEE,EAAE,QAAQH,EAAE,WAAW,IAAI,IAAIA,EAAEqD,YAAYkB,iBAAiB,cAAc,IAAI,WAAW,IAAIxE,EAAEsD,YAAYmB,OAAOxE,EAAE,CAAC6D,UAAU,aAAaX,UAAU,GAAG,IAAI,IAAIjD,KAAKF,EAAE,oBAAoBE,GAAG,WAAWA,IAAID,EAAEC,GAAGW,KAAK6D,IAAI1E,EAAEE,GAAGF,EAAE2E,gBAAgB,IAAI,OAAO1E,EAAhL,GAAqLC,EAAEI,MAAMJ,EAAEK,MAAMN,EAAE2E,cAAc1E,EAAEM,QAAQ,CAACP,GAAGD,EAAEE,GAAG,MAAMF,MAAM,aAAa6B,SAASgD,WAAW7B,WAAW/C,EAAE,GAAG2B,iBAAiB,WAAW3B","file":"static/js/3.d0d355a5.chunk.js","sourcesContent":["var t,e,n,i,a=function(t,e){return{name:t,value:void 0===e?-1:e,delta:0,entries:[],id:\"v1-\".concat(Date.now(),\"-\").concat(Math.floor(8999999999999*Math.random())+1e12)}},r=function(t,e){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var n=new PerformanceObserver((function(t){return t.getEntries().map(e)}));return n.observe({type:t,buffered:!0}),n}}catch(t){}},o=!1,c=function(t,e){o||\"undefined\"!=typeof InstallTrigger||(addEventListener(\"beforeunload\",(function(){})),o=!0);addEventListener(\"visibilitychange\",(function n(i){\"hidden\"===document.visibilityState&&(t(i),e&&removeEventListener(\"visibilitychange\",n,!0))}),!0)},u=function(t){addEventListener(\"pageshow\",(function(e){e.persisted&&t(e)}),!0)},f=\"function\"==typeof WeakSet?new WeakSet:new Set,s=function(t,e,n){var i;return function(){e.value>=0&&(n||f.has(e)||\"hidden\"===document.visibilityState)&&(e.delta=e.value-(i||0),(e.delta||void 0===i)&&(i=e.value,t(e)))}},m=function(t,e){var n,i=a(\"CLS\",0),o=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),n())},f=r(\"layout-shift\",o);f&&(n=s(t,i,e),c((function(){f.takeRecords().map(o),n()})),u((function(){i=a(\"CLS\",0),n=s(t,i,e)})))},d=-1,v=function(){return\"hidden\"===document.visibilityState?0:1/0},p=function(){c((function(t){var e=t.timeStamp;d=e}),!0)},l=function(){return d<0&&(d=v(),p(),u((function(){setTimeout((function(){d=v(),p()}),0)}))),{get timeStamp(){return d}}},S=function(t,e){var n,i=l(),o=a(\"FCP\"),c=r(\"paint\",(function(t){\"first-contentful-paint\"===t.name&&(c&&c.disconnect(),t.startTime=0&&e1e12?new Date:performance.now())-t.timeStamp;\"pointerdown\"==t.type?function(t,e){var n=function(){g(t,e),a()},i=function(){a()},a=function(){removeEventListener(\"pointerup\",n,h),removeEventListener(\"pointercancel\",i,h)};addEventListener(\"pointerup\",n,h),addEventListener(\"pointercancel\",i,h)}(e,t):g(e,t)}},L=function(t){[\"mousedown\",\"keydown\",\"touchstart\",\"pointerdown\"].forEach((function(e){return t(e,w,h)}))},T=function(n,o){var m,d=l(),v=a(\"FID\"),p=function(t){t.startTime 20 | #include 21 | 22 | #include "curl/curl.h" 23 | 24 | #include "S3_HLS_SDK.h" 25 | #include "S3_HLS_Return_Code.h" 26 | #include "S3_HLS_Buffer_Mgr.h" 27 | #include "S3_HLS_Pes.h" 28 | #include "S3_HLS_Upload_Thread.h" 29 | #include "S3_HLS_S3_Put_Client.h" 30 | #include "S3_HLS_Queue.h" 31 | 32 | #define S3_HLS_TS_OBJECT_KEY_FORMAT "%s/%04d/%02d/%02d/%02d/%02d/%02d.ts" 33 | 34 | #define S3_HLS_SDK_EMPTY_STRING "" 35 | 36 | #define S3_HLS_SDK_DEBUG 37 | 38 | #ifdef S3_HLS_SDK_DEBUG 39 | #define SDK_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 40 | #else 41 | #define SDK_DEBUG(x, ...) 42 | #endif 43 | 44 | static S3_HLS_QUEUE_CTX* s3_hls_queue_ctx = NULL; 45 | static S3_HLS_BUFFER_CTX* s3_hls_buffer_ctx = NULL; 46 | static S3_HLS_THREAD_CTX* s3_hls_worker_thread = NULL; 47 | static S3_HLS_CLIENT_CTX* s3_client = NULL; 48 | 49 | static sem_t s3_hls_put_send_sem; 50 | 51 | static char* object_prefix = NULL; 52 | 53 | static char object_key_buffer[S3_HLS_MAX_KEY_LENGTH + 1]; 54 | 55 | /* 56 | */ 57 | static void S3_HLS_Upload_Queue_Item() { 58 | SDK_DEBUG("Ready For Upload!\n"); 59 | int32_t ret = sem_wait(&s3_hls_put_send_sem); 60 | if(0 != ret) { 61 | SDK_DEBUG("Error Semaphore impared! %d\n", ret); 62 | } 63 | 64 | S3_HLS_BUFFER_PART_CTX part_ctx; 65 | ret = S3_HLS_Get_Item_From_Queue(s3_hls_queue_ctx, &part_ctx); 66 | 67 | if(S3_HLS_OK != ret) { 68 | SDK_DEBUG("Failed to get item from queue!\n"); 69 | return; 70 | } 71 | 72 | struct tm* time_tm = gmtime(&part_ctx.timestamp); 73 | 74 | if(0 >= sprintf(object_key_buffer, S3_HLS_TS_OBJECT_KEY_FORMAT, object_prefix ? object_prefix : S3_HLS_SDK_EMPTY_STRING, time_tm->tm_year + 1900, time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec)) { 75 | SDK_DEBUG("Unkown Internal Error!\n"); 76 | return; 77 | } 78 | 79 | SDK_DEBUG("Get Queue Info!\n"); 80 | SDK_DEBUG("Queue Info: %p, %d, %p, %d\n", part_ctx.first_part_start, part_ctx.first_part_length, part_ctx.second_part_start, part_ctx.second_part_length); 81 | S3_HLS_Client_Upload_Buffer(s3_client, object_key_buffer, part_ctx.first_part_start, part_ctx.first_part_length, part_ctx.second_part_start, part_ctx.second_part_length); 82 | 83 | SDK_DEBUG("Upload Complete, Clear Queue Buffer!\n"); 84 | 85 | if(S3_HLS_OK != S3_HLS_Release_Queue(s3_hls_queue_ctx)) { 86 | SDK_DEBUG("Release Queue Failed!\n"); 87 | return; 88 | } 89 | 90 | if(S3_HLS_OK != S3_HLS_Lock_Buffer(s3_hls_buffer_ctx)) { 91 | SDK_DEBUG("Get Buffer Lock Failed!\n"); 92 | return; 93 | } 94 | 95 | SDK_DEBUG("Release Buffer!\n"); 96 | S3_HLS_Clear_Buffer(s3_hls_buffer_ctx, &part_ctx); 97 | 98 | if(S3_HLS_OK != S3_HLS_Unlock_Buffer(s3_hls_buffer_ctx)) { 99 | SDK_DEBUG("Get Buffer Unlock Failed!\n"); 100 | return; 101 | } 102 | } 103 | 104 | /* 105 | */ 106 | static void S3_HLS_Add_Buffer_To_Queue(S3_HLS_BUFFER_PART_CTX* ctx) { 107 | SDK_DEBUG("Adding buffer to queue!\n"); 108 | if(NULL == ctx) { 109 | SDK_DEBUG("Invalid CTX!\n"); 110 | return; 111 | } 112 | 113 | if(NULL == ctx->first_part_start && 0 != ctx->first_part_length) { 114 | SDK_DEBUG("Invalid First Part!\n"); 115 | return; 116 | } 117 | 118 | if(NULL == ctx->second_part_start && 0 != ctx->second_part_length) { 119 | SDK_DEBUG("Invalid Second Part!\n"); 120 | return; 121 | } 122 | 123 | if(0 == ctx->first_part_length + ctx->second_part_length) { 124 | SDK_DEBUG("Empty Part!\n"); 125 | return; 126 | } 127 | 128 | int32_t ret = S3_HLS_Add_To_Queue(s3_hls_queue_ctx, ctx->first_part_start, ctx->first_part_length, ctx->second_part_start, ctx->second_part_length, ctx->timestamp); 129 | if(0 != ret) { 130 | // unknown error 131 | SDK_DEBUG("Add item to queue failed! %d\n", ret); 132 | return; 133 | } 134 | 135 | SDK_DEBUG("Added to queue!\n"); 136 | 137 | ret = sem_post(&s3_hls_put_send_sem); 138 | if(0 != ret) { 139 | SDK_DEBUG("Error, post semaphore failed! %d\n", ret); 140 | } 141 | } 142 | 143 | /* 144 | * Initialize S3 client 145 | * Parameters: 146 | * region - provide the region code like "us-east-1" where the bucket is created 147 | * bucket - name of video bucket 148 | * prefix - path to store the video in the bucket. Usually this is the certificate iD of the IPC when using AWS IoT Things Management 149 | * endpoint - optional parameter, if using default endpiont then can set this parameter to NULL 150 | * 151 | * Note: 152 | * These paremeters are not allowed to change after initialized. 153 | */ 154 | int32_t S3_HLS_SDK_Initialize(uint32_t buffer_size, char* region, char* bucket, char* prefix, char* endpint) { 155 | SDK_DEBUG("SDK Init!\n"); 156 | 157 | CURLcode res = curl_global_init(CURL_GLOBAL_DEFAULT); 158 | 159 | /* Check for errors */ 160 | if(res != CURLE_OK) { 161 | SDK_DEBUG("CURL Init Failed!\n"); 162 | goto l_cleanup_curl; 163 | } 164 | 165 | if(0 !=sem_init(&s3_hls_put_send_sem, 0 ,0)) { 166 | SDK_DEBUG("Semaphore Init Failed!\n"); 167 | goto l_cleanup_curl; 168 | } 169 | 170 | SDK_DEBUG("SDK Buffer Init!\n"); 171 | s3_hls_buffer_ctx = S3_HLS_Initialize_Buffer(buffer_size, S3_HLS_Add_Buffer_To_Queue); 172 | if(NULL == s3_hls_buffer_ctx) { 173 | SDK_DEBUG("Buffer Init Failed!\n"); 174 | goto l_cleanup_curl; 175 | } 176 | 177 | SDK_DEBUG("SDK S3 Client Init!\n"); 178 | // initialize S3 upload process 179 | s3_client = S3_HLS_Client_Initialize(region, bucket, endpint); 180 | if(NULL == s3_client) { 181 | SDK_DEBUG("S3 Client Init Failed!\n"); 182 | goto l_finalize_buffer; 183 | } 184 | 185 | SDK_DEBUG("Upload Thread Init!\n"); 186 | s3_hls_worker_thread = S3_HLS_Upload_Thread_Initialize(S3_HLS_Upload_Queue_Item); 187 | if(NULL == s3_hls_worker_thread) { 188 | SDK_DEBUG("Upload Thread Init Failed!\n"); 189 | goto l_finalize_client; 190 | } 191 | 192 | s3_hls_queue_ctx = S3_HLS_Initialize_Queue(); 193 | if(NULL == s3_hls_queue_ctx) { 194 | SDK_DEBUG("Upload Queue Init Failed!\n"); 195 | goto l_finalize_client; 196 | } 197 | 198 | object_prefix = prefix; 199 | 200 | SDK_DEBUG("SDK Init Finished!\n"); 201 | return S3_HLS_OK; 202 | 203 | l_finalize_client: 204 | S3_HLS_Client_Finalize(s3_client); 205 | s3_client = NULL; 206 | 207 | l_finalize_buffer: 208 | S3_HLS_Finalize_Buffer(s3_hls_buffer_ctx); 209 | s3_hls_buffer_ctx = NULL; 210 | 211 | l_cleanup_curl: 212 | curl_global_cleanup(); 213 | 214 | return S3_HLS_UNKNOWN_INTERNAL_ERROR; 215 | } 216 | 217 | /* 218 | * Update Credential used to connect to S3 219 | * The credential is locked during generating request headers for SIgnature V4. And will release the lock during uploading. 220 | * Parameter: 221 | * ak - Access Key 222 | * sk - Secret Access Key 223 | * token - token generated by STS for temporary credential 224 | * 225 | * Note: 226 | * Suggest to use this SDK with AWS IoT Things Management. JITP will be a good choice. 227 | * Suggest to rotate credential several minutes/seconds before old credential expires to avoid unsuccessful upload 228 | */ 229 | int32_t S3_HLS_SDK_Set_Credential(char* ak, char* sk, char* token) { 230 | return S3_HLS_Client_Set_Credential(s3_client, ak, sk, token); 231 | } 232 | 233 | /* 234 | * Call this function to set upload tag for item 235 | */ 236 | int32_t S3_HLS_SDK_Set_Tag(char* object_tag) { 237 | return S3_HLS_Client_Set_Tag(s3_client, object_tag); 238 | } 239 | 240 | /* 241 | * Start a back ground thread for uploading 242 | */ 243 | int32_t S3_HLS_SDK_Start_Upload() { 244 | return S3_HLS_Upload_Thread_Start(s3_hls_worker_thread); 245 | } 246 | 247 | /* 248 | * Finalize will release resources allocated 249 | * Note: Finalize will not free input parameter like ak, sk, token, region, bucket, prefix, endpoint etc. 250 | */ 251 | int32_t S3_HLS_SDK_Finalize() { 252 | S3_HLS_Flush_Buffer(s3_hls_buffer_ctx); 253 | 254 | S3_HLS_Upload_Thread_Stop(s3_hls_worker_thread); 255 | 256 | S3_HLS_Client_Finalize(s3_client); 257 | 258 | S3_HLS_Finalize_Buffer(s3_hls_buffer_ctx); 259 | 260 | S3_HLS_Finalize_Queue(s3_hls_queue_ctx); 261 | 262 | sem_destroy(&s3_hls_put_send_sem); 263 | 264 | curl_global_cleanup(); 265 | 266 | return S3_HLS_OK; 267 | } 268 | 269 | /* 270 | * User call this method to put video stream into buffer 271 | * The pack contains an array of H264 frames. 272 | * For most of the time, each image pack will contain only one frame 273 | * But usually SPS/PPS/SEI frames comes together with I frame within a pack 274 | * In that case, the pack will contains 4 frames 275 | */ 276 | int32_t S3_HLS_SDK_Put_Video_Frame(S3_HLS_FRAME_PACK* pack) { 277 | return S3_HLS_Pes_Write_Video_Frame(s3_hls_buffer_ctx, pack); 278 | } 279 | 280 | /* 281 | * User call this method to put audio stream into buffer 282 | * Currently the only supported audio frame type is AAC encoded frame 283 | */ 284 | int32_t S3_HLS_SDK_Put_Audio_Frame(S3_HLS_FRAME_PACK* pack) { 285 | return S3_HLS_Pes_Write_Audio_Frame(s3_hls_buffer_ctx, pack); 286 | } -------------------------------------------------------------------------------- /demosite/static/css/main.3cb751cd.chunk.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://src/index.scss"],"names":[],"mappings":"AAAA,KAEE,mJAC4C,CAC5C,kCAAmC,CACnC,iCAAkC,CAClC,UAAW,CACX,eAAgB,CAChB,wBAAyB,CACzB,cAAe,CAChB,OATC,QAcsB,CALvB,EAIC,SAAU,CACV,qBAAsB,CACvB,MAIC,eAAgB,CACjB,mBAGC,8BAAgC,CACjC,SAGC,sBAAwB,CACzB,YAGC,gBAAiB,CAClB,WAGC,eAAgB,CAKjB,0BADC,iBAKkB,CAJnB,aAIC,iBAAkB,CACnB,KAGC,yEAA+E,CAChF,SAGC,iBAAkB,CAClB,gBAAiB,CAClB,WAGC,cAAe,CACf,UAAW,CACX,qBAAsB,CACtB,SAAU,CACV,WAAY,CACZ,WAAY,CANd,kBAQI,wBAAyB,CAEzB,cAAe,CAEf,+BAAgC,CAChC,iBAAkB,CAbtB,yBAeM,iBAAkB,CAClB,UAAW,CACX,QAAS,CACT,cAAe,CAlBrB,iBAsBI,wBAAyB,CAtB7B,2CAyBM,UAAW,CACX,aAAc,CACd,sBAAyB,CA3B/B,yDA6BQ,eAAiB,CACjB,aAAc,CACf,YAML,cAAe,CACf,UAAc,CACd,eAAgB,CAChB,gBAAiB,CACjB,gBAAmB,CACnB,iBAAkB,CANpB,yBAQI,iBAAkB,CAClB,OAAU,CACV,QAAS,CACV,iBAID,YAAa,CACb,kBAAmB,CAFrB,6BAQI,WAAY,CACZ,YAAa,CAEb,wBAAyB,CACzB,qBAAsB,CAZ1B,iCAcM,qBAAsB,CAd5B,mCAiBM,iBAAoB,CACpB,cAAe,CAEf,UAAW,CApBjB,mCAuBM,wBAAyB,CAC1B,6BAMD,cAAe,CACf,aAAc,CACd,eAAgB,CAChB,gBAAiB,CALrB,oCASM,eAAmB,CACnB,uCAA4C,CAC5C,YAAa,CACb,YAAa,CACb,kBAAmB,CACnB,cAAe,CAdrB,4CAgBQ,UAAW,CACX,aAAc,CACd,UAAW,CACX,iBAAkB,CAClB,YAAa,CApBrB,mCAwBM,SAAU,CACV,WAAY,CAzBlB,0CA2BQ,iBAAkB,CA3B1B,iDA6BU,iBAAkB,CAClB,oBAAsB,CA9BhC,yCAkCQ,cAAe,CACf,UAAW,CACZ,oBAOH,cAAe,CACf,UAAc,CACd,eAAgB,CAChB,iBAAkB,CAClB,mBAAoB,CANxB,0BAQM,UAAW,CACZ,YAKH,YAAa,CACb,kBAAmB,CACnB,+BAAgC,CAChC,eAAgB,CAJlB,iBAOI,cAAe,CACf,gBAAiB,CACjB,WAAY,CACZ,2BAA4B,CAC5B,kBAAmB,CAEnB,gBAAiB,CACjB,iBAAkB,CAClB,cAAe,CACf,iBAAkB,CAhBtB,wBAkBM,eAAiB,CACjB,aAAc,CAnBpB,8BAqBQ,iBAAkB,CAClB,MAAO,CACP,YAAa,CACb,UAAW,CACX,WAAY,CACZ,UAAW,CACX,qBAAsB,CACvB,oBAML,cAAe,CADjB,uCAGI,YAAa,CACb,kBAAmB,CAEnB,kBAAmB,CANvB,0DAQM,iBAAkB,CAClB,gBAAiB,CACjB,eAAmB,CACnB,wBAAyB,CAEzB,iBAAkB,CAClB,cAAe,CAdrB,iEAgBQ,aAAc,CACd,wBAAyB,CAjBjC,oCAsBI,YAAa,CACb,cAAe,CAEf,kBAAmB,CACnB,SAAc,CA1BlB,4BA6BI,eAAgB,CAajB,KAID,UAAW,CACX,eAAgB,CAFlB,iBAII,cAAe,CACf,UAAW,CACX,UAAW,CACX,MAAO,CACP,KAAM,CACN,WAAY,CACZ,wBAAyB,CACzB,UAAW,CACX,YAAa,CACb,kBAAmB,CACnB,kBAAmB,CAEnB,cAAe,CAhBnB,uBAkBM,cAAe,CACf,eAAiB,CACjB,iBAAkB,CAClB,QAAO,CArBb,2BAuBQ,iBAAkB,CAClB,iBAAkB,CAClB,eAAgB,CAzBxB,uBA8BM,eAAgB,CAChB,gBAAiB,CA/BvB,uDAkCQ,UAAW,CAlCnB,iBAuCI,cAAe,CACf,UAAW,CACX,WAAY,CACZ,gBAAiB,CACjB,QAAS,CACT,MAAO,CACP,UAAW,CACX,qBAAsB,CACtB,uCAA4C,CAC5C,YAAa,CACb,kBAAmB,CAjDvB,uBAoDM,UAAW,CACX,iBAAkB,CAClB,gBAAiB,CACjB,cAAe,CAvDrB,wBA0DM,QAAO,CACP,6BAA8B,CAC9B,8BAA+B,CAC/B,cAAe,CA7DrB,eAiEI,6BAA8B,CAC9B,gBAAqB,CAlEzB,wBAqEM,gBAAiB,CACjB,mBAAoB,CAtE1B,iBA0EI,WAAY,CACZ,wBAAyB,CACzB,UAAW,CAEX,YAAa,CACb,kBAAmB,CACnB,kBAAmB,CAhFvB,uBAkFM,cAAe,CACf,gBAAiB,CACjB,iBAAkB,CAClB,eAAiB,CACjB,cAAe,CAtFrB,6BAwFQ,iBAAkB,CAClB,iBAAkB,CAClB,eAAgB,CACjB,yBAQL,WACE,QAAS,CACT,UAAW,CACZ,iBAGC,aAAc,CADhB,6BAGI,SAAU,CACV,aAAc,CACf,mCAKG,SAAU,CACX,oBAKH,cAAe,CADjB,uCAGI,6BAA8B,CAHlC,oCAMI,aAAc,CANlB,wCAQM,kBAAmB,CARzB,4BAaI,gBAAiB,CAClB,iBAIC,WAAY,CAFhB,iBAKI,WAAY,CACZ,QAAS,CANb,eASI,6BAA8B,CATlC,wBAWM,eAAgB,CACjB","file":"main.3cb751cd.chunk.css","sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Roboto\", \"Oxygen\", \"Ubuntu\", \"Cantarell\", \"Fira Sans\",\n \"Droid Sans\", \"Helvetica Neue\", sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n width: 100%;\n min-height: 100%;\n background-color: #f2f3f3;\n font-size: 14px;\n}\n\n* {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n}\n\nul,\nli {\n list-style: none;\n}\n\na:-webkit-any-link {\n text-decoration: none !important;\n}\n\n.no-show {\n display: none !important;\n}\n\n.text-right {\n text-align: right;\n}\n\n.text-left {\n text-align: left;\n}\n\n.text-center {\n text-align: center;\n}\n\n.app-loading {\n text-align: center;\n margin: 100px auto;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\n\n.loading {\n text-align: center;\n padding-top: 20px;\n}\n\n.side-menu {\n position: fixed;\n z-index: 99;\n background-color: #fff;\n top: 101px;\n width: 280px;\n bottom: 30px;\n .title {\n padding: 15px 0 15px 30px;\n // font-weight: bold;\n font-size: 18px;\n // line-height: 2rem;\n border-bottom: 1px solid #eaeded;\n position: relative;\n .close {\n position: absolute;\n right: 15px;\n top: 14px;\n cursor: pointer;\n }\n }\n .menu {\n padding: 10px 0 10px 30px;\n a,\n a:link {\n color: #444;\n display: block;\n padding: 8px 10px 8px 0px;\n &.active {\n font-weight: bold;\n color: #ec7211;\n }\n }\n }\n}\n\n.page-title {\n font-size: 28px;\n color: #000000;\n text-align: left;\n line-height: 36px;\n padding: 0 0 20px 0;\n position: relative;\n .back-button {\n position: absolute;\n right: 0px;\n top: -3px;\n }\n}\n\n.ipc-device-list {\n display: flex;\n flex-direction: row;\n // justify-content: space-between;\n // text-align: center;\n // flex-wrap: wrap;\n .ipc-device {\n // display: inline-block;\n width: 240px;\n padding: 10px;\n // margin: 0 auto;\n border: 1px solid #aab7b8;\n background-color: #fff;\n img {\n border: 1px solid #ddd;\n }\n .name {\n padding: 5px 0 3px 0;\n font-size: 16px;\n // font-weight: bold;\n color: #444;\n }\n &:hover {\n background-color: #f1faff;\n }\n }\n}\n\n.ipc-video-list {\n .result-info {\n font-size: 14px;\n color: #393939;\n text-align: left;\n padding: 10px 5px;\n }\n .videos {\n .video-more {\n background: #ffffff;\n box-shadow: 0 1px 2px 0 rgba(0, 28, 36, 0.3);\n padding: 10px;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n .loader {\n color: #999;\n display: block;\n width: 100%;\n text-align: center;\n padding: 10px;\n }\n }\n .ipc-video {\n width: 20%;\n padding: 5px;\n .image {\n position: relative;\n .human {\n position: absolute;\n border: 1px solid #f00;\n }\n }\n .time {\n font-size: 16px;\n color: #444;\n }\n }\n }\n}\n\n.video-replay {\n .time {\n font-size: 16px;\n color: #000000;\n text-align: left;\n line-height: 1.6em;\n padding-bottom: 10px;\n label {\n color: #444;\n }\n }\n}\n\n.search-tab {\n display: flex;\n flex-direction: row;\n border-bottom: 1px solid #d5dbdb;\n margin-top: 10px;\n .tab {\n // flex: 1;\n font-size: 14px;\n line-height: 22px;\n width: 120px;\n border-right: 1px solid #ccc;\n margin-bottom: 10px;\n // padding: 10px 20px;\n padding: 3px 10px;\n text-align: center;\n cursor: pointer;\n position: relative;\n &.active {\n font-weight: bold;\n color: #ec7211;\n &::after {\n position: absolute;\n left: 0;\n bottom: -11px;\n width: 100%;\n content: \" \";\n height: 2px;\n background-color: #000;\n }\n }\n }\n}\n\n.search-tab-content {\n padding: 15px 0;\n .quick-search-list {\n display: flex;\n flex-direction: row;\n // justify-content: space-between;\n align-items: center;\n .quick-search-item {\n margin-right: 10px;\n padding: 7px 14px;\n background: #ffffff;\n border: 1px solid #545b64;\n border-radius: 2px;\n border-radius: 2px;\n cursor: pointer;\n &.active {\n color: #ec7211;\n border: 1px solid #ec7211;\n }\n }\n }\n .precise-search {\n display: flex;\n flex-wrap: wrap;\n // justify-content: space-between;\n align-items: center;\n padding: 0px 0;\n }\n .search {\n margin-top: 20px;\n // padding-top: 10px;\n // .search-btn {\n // font-weight: bold;\n // background: #ec7211;\n // border: 1px solid #ec7211;\n // border-radius: 2px;\n // border-radius: 2px;\n // padding: 8px 20px;\n // color: #fff;\n // margin-top: 10px;\n // cursor: pointer;\n // }\n }\n}\n\n.App {\n width: 100%;\n min-height: 100%;\n .ipc-header {\n position: fixed;\n z-index: 99;\n width: 100%;\n left: 0;\n top: 0;\n height: 60px;\n background-color: #232f3e;\n color: #fff;\n display: flex;\n flex-direction: row;\n align-items: center;\n // justify-content: space-between;\n padding: 0 20px;\n .logo {\n font-size: 18px;\n font-weight: bold;\n padding-left: 20px;\n flex: 1;\n img {\n position: absolute;\n margin-left: -25px;\n margin-top: -2px;\n }\n }\n .user {\n // width: 50px;\n margin-left: 5px;\n text-align: right;\n a,\n a:link {\n color: #fff;\n }\n }\n }\n .breadcrumb {\n position: fixed;\n z-index: 99;\n height: 40px;\n line-height: 40px;\n top: 60px;\n left: 0;\n width: 100%;\n background-color: #fff;\n box-shadow: 0 1px 2px 0 rgba(0, 28, 36, 0.3);\n display: flex;\n align-items: center;\n\n .icon {\n width: 40px;\n text-align: center;\n padding-top: 12px;\n cursor: pointer;\n }\n .bread {\n flex: 1;\n border-left: 1px solid #d5dbdb;\n border-right: 1px solid #d5dbdb;\n padding: 0 10px;\n }\n }\n .ipc-body {\n min-height: calc(100vh - 30px);\n padding: 0px 0px 10px;\n\n .content {\n margin-top: 100px;\n padding: 0 15px 15px;\n }\n }\n .ipc-footer {\n height: 30px;\n background-color: #232f3e;\n color: #fff;\n // padding: 6px 15px 0 15px;\n display: flex;\n flex-direction: row;\n align-items: center;\n .item {\n font-size: 12px;\n margin-left: 15px;\n padding-left: 30px;\n font-weight: bold;\n cursor: pointer;\n .icon {\n margin-left: -25px;\n position: absolute;\n margin-top: -3px;\n }\n }\n }\n}\n\n/* Using SCSS variables to store breakpoints */\n$breakpoint-tablet: 768px;\n@media (max-width: $breakpoint-tablet) {\n .side-menu {\n top: 40px;\n width: 100%;\n }\n\n .ipc-device-list {\n display: block;\n .ipc-device {\n width: 60%;\n margin: 0 auto;\n }\n }\n .ipc-video-list {\n .videos {\n .ipc-video {\n width: 33%;\n }\n }\n }\n\n .search-tab-content {\n padding: 15px 0;\n .quick-search-list {\n justify-content: space-between;\n }\n .precise-search {\n display: block;\n > div {\n margin-bottom: 10px;\n }\n // justify-content: space-between;\n }\n .search {\n text-align: right;\n }\n }\n .App {\n .ipc-header {\n height: 40px;\n }\n .breadcrumb {\n height: 40px;\n top: 40px;\n }\n .ipc-body {\n min-height: calc(100vh - 30px);\n .content {\n margin-top: 80px;\n }\n }\n }\n}\n"]} -------------------------------------------------------------------------------- /demosite/static/js/runtime-main.ec776a9b.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["../webpack/bootstrap"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","1","exports","module","l","e","promises","installedChunkData","promise","Promise","resolve","reject","onScriptComplete","script","document","createElement","charset","timeout","nc","setAttribute","src","p","jsonpScriptSrc","error","Error","event","onerror","onload","clearTimeout","chunk","errorType","type","realSrc","target","message","name","request","undefined","setTimeout","head","appendChild","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","err","console","jsonpArray","this","oldJsonpFunction","slice"],"mappings":"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","file":"static/js/runtime-main.ec776a9b.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t1: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"static/js/\" + ({}[chunkId]||chunkId) + \".\" + {\"3\":\"d0d355a5\"}[chunkId] + \".chunk.js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = this[\"webpackJsonpip-camera-ui\"] = this[\"webpackJsonpip-camera-ui\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// run deferred modules from other chunks\n \tcheckDeferredModules();\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /S3_HLS_TS.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | 20 | /* 21 | *. Format: 22 | * 23 | *. Sync_word; // 8 bits 0x47 24 | * transport_error; // 1 bit 0b0 (0x80) 25 | * payload_start; // 1 bit 0b0 (0x40) 26 | * transport_priority; // 1 bit 0b0 (0x20) 27 | * pid; // 13 bits 0x1FFF range, 0x0000 for PAT 0x1000 for PMT 0x0100 for video 0x0101 for audio 28 | * scrambling_control; // 2 bits 0b00 (0xC0) 29 | * adaptation_field; // 2 bits 0b?1 (0x30 or 0x10) 30 | * counter; // 4 bits 0b0000 (0x0F) 31 | * 32 | * // adaption part 33 | * adaption_length; // 8 bits only exists when adaptation_field & 0x20 34 | * 35 | * discontinuity; // 1 bit 0b0 (0x80) 36 | * random_access; // 1 bit 0b? (0x40) set by user 37 | * stream_priority; // 1 bit 0b0 (0x20) 38 | * 39 | * pcr_field; // 1 bit 0b0 (0x10) when 1 will have 48 bits PCR 40 | * opcr_filed; // 1 bit 0b0 (0x08) when 1 will have 48 bits OPCR 41 | * splicing_point_flag; // 1 bit 0b0 (0x04) when 1 will have 8 bits splice count down 42 | * transport_private_data_flag; // 1 bit 0b0 (0x02) when 1 will have 8 bits private data length and 8*n bits of private data 43 | * adaptation_field_extension_flag; // 1 bit 0b0 (0x01) when 1 will have 8 bits adaption field entension length 44 | * 45 | * // when pcr_field = 1 // 48 bits 46 | * pcr_high[33]; 47 | * pcr_reserved[6]; 48 | * pcr_low[9]; 49 | * 50 | * // when opcr_field = 1 // 48 bits 51 | * opcr_high[33]; 52 | * opcr_reserved[6]; 53 | * opcr_low[9]; 54 | * 55 | * // when splicing_point_flag = 1 56 | * splice_countdown; // 8 bits 57 | * 58 | * // when transport_private_data_flag = 1 59 | * private_data_length; // 8 bits 60 | * private_data[private_data_length]; // 8 * private_data_length bits 61 | * 62 | * // when adaptation_field_extension_flag = 1 63 | * adaptation_field_extension_length; // 8 bits 64 | * 65 | * ltw_flag; // 1 bit 66 | * piecewise_rate_flag; // 1 bit 67 | * seamless_splice_flag; // 1 bit 68 | * reserved; // 5 bits 69 | * 70 | * // when ltw_flag = 1 71 | * ltw_valid_flag; // 1 bit 72 | * ltw_offset; // 15 bits 73 | * 74 | * // when piecewise_rate_flag = 1 75 | * reserved; // 2 bits 76 | * piecewise_rate_flag; // 22 bits 77 | * 78 | * // when seamless_splice_flag = 1 79 | * splice_type; // 4 bits 80 | * dts_next_au_32_30; // 3 bits 81 | * marker_bit; // 1 bit 82 | * dts_next_au_29_15; // 15 bits 83 | * marker_bit; // 1 bit 84 | * dts_next_au_14_0; // 15 bits 85 | * marker_bit; // 1 bit 86 | * 87 | * // to end of adaptation_field_extension_length 88 | * unsigned char reserved; // 89 | * 90 | * // to end of adaption_length 91 | * unsigned char stuffing_bytes; // 0xFF 92 | * 93 | */ 94 | 95 | #include 96 | #include 97 | #include 98 | 99 | #include "S3_HLS_TS.h" 100 | #include "S3_HLS_Buffer_Mgr.h" 101 | #include "S3_HLS_Return_Code.h" 102 | 103 | #define S3_HLS_TS_PAYLOAD_START_POS 1 104 | #define S3_HLS_TS_PID_HIGH_POS 1 105 | #define S3_HLS_TS_PID_LOW_POS 2 106 | #define S3_HLS_TS_ADOPTION_FLAG_POS 3 107 | #define S3_HLS_TS_ADOPTION_LENGTH_POS 4 108 | #define S3_HLS_TS_RANDOM_ACCESS_FLAG_POS 5 109 | #define S3_HLS_TS_PCR_FLAG_POS 5 110 | 111 | #define S3_HLS_PCR_START_POS 6 112 | 113 | #define S3_HLS_TS_PAYLOAD_START_FLAG 0x40 114 | #define S3_HLS_TS_PID_HEX_CODE 0x1FFF 115 | #define S3_HLS_TS_RANDOM_ACCESS_FLAG 0x40 116 | #define S3_HLS_TS_PCR_FLAG 0x10 117 | #define S3_HLS_TS_ADOPTION_FLAG 0x20 118 | 119 | // #define S3_HLS_TS_DEBUG 120 | 121 | #ifdef S3_HLS_TS_DEBUG 122 | #define TS_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 123 | #else 124 | #define TS_DEBUG(x, ...) 125 | #endif 126 | 127 | uint8_t ts_header[12] = { 0x47, /* Start Code */ 128 | 0x00, /* 3 bit flags only 0x40 is used as payload start, other 5 bits are first 5 bits of PID */ 129 | 0x00, /* last 8 bits of pid 0x100 is video ,0x101 is audio */ 130 | 0x10, /* 0x30 has adoption field, 0x10 doesn't have aoption field, and last 4 bits are ts counter */ 131 | 132 | 0x00, /* adoption length only exists when 4th bytes contains 0x20 flag */ 133 | 134 | 0x00, /* adoption flag fields only exists when 5th bytes >= 1 */ 135 | 136 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* PCR field only exists when */ 137 | }; // last 4 bytes are crc 138 | 139 | int8_t m_ts_video_counter = 0; 140 | int8_t m_ts_audio_counter = 0; 141 | 142 | 143 | /* 144 | * Clear flags and prepare for next TS header 145 | * Call this function after write to buffer 146 | */ 147 | void S3_HLS_TS_Reset_Header_Info() { 148 | ts_header[1] = 0; 149 | ts_header[2] = 0; 150 | ts_header[3] = 0x10; 151 | ts_header[4] = 0; 152 | ts_header[5] = 0; 153 | ts_header[6] = 0; 154 | ts_header[7] = 0; 155 | ts_header[8] = 0; 156 | ts_header[9] = 0; 157 | ts_header[10] = 0; 158 | ts_header[11] = 0; 159 | } 160 | 161 | /* 162 | * Call this function to write TS header and adoption field to buffer 163 | */ 164 | int32_t S3_HLS_TS_Write_To_Buffer(S3_HLS_BUFFER_CTX* ctx) { 165 | uint32_t ret = 0; 166 | uint32_t pid = ts_header[S3_HLS_TS_PID_HIGH_POS] & 0x1F; 167 | pid *= 256; 168 | pid += ts_header[S3_HLS_TS_PID_LOW_POS]; 169 | 170 | ts_header[S3_HLS_TS_COUNTER_INDEX] &= 0xF0; 171 | switch(pid) { 172 | case S3_HLS_Video_PID: 173 | ts_header[S3_HLS_TS_COUNTER_INDEX] |= (m_ts_video_counter & 0x0F); 174 | break; 175 | case S3_HLS_Audio_PID: 176 | ts_header[S3_HLS_TS_COUNTER_INDEX] |= (m_ts_audio_counter & 0x0F); 177 | break; 178 | } 179 | 180 | // write to buffer 181 | uint8_t* first_part_start = ts_header; 182 | uint32_t first_part_length = 4; 183 | 184 | uint8_t* second_part_start = NULL; 185 | uint32_t second_part_length = 0; 186 | 187 | if(ts_header[S3_HLS_TS_ADOPTION_FLAG_POS] & S3_HLS_TS_ADOPTION_FLAG) { // do have adoption field 188 | first_part_length++; // adoption length field 189 | if(ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] > 0) { 190 | if(ts_header[S3_HLS_TS_PCR_FLAG_POS] & S3_HLS_TS_PCR_FLAG) { 191 | first_part_length += 7; // adoption flags 1 + pcr 6 192 | } else { 193 | first_part_length += 1; // adoption flags 1 194 | } 195 | } 196 | 197 | if(ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] > first_part_length - 5) { 198 | // need to fill remaining fields 199 | second_part_start = const_fill_word; 200 | second_part_length = ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] - (first_part_length - 5); 201 | } 202 | } 203 | 204 | ret = S3_HLS_Put_To_Buffer(ctx, first_part_start, first_part_length); 205 | if(0 > ret) 206 | return ret; 207 | 208 | int32_t length = ret; 209 | ret = S3_HLS_Put_To_Buffer(ctx, second_part_start, second_part_length); 210 | if(0 > ret) 211 | return ret; 212 | 213 | length += ret; 214 | 215 | S3_HLS_TS_Reset_Header_Info(); 216 | 217 | switch(pid) { 218 | case S3_HLS_Video_PID: 219 | m_ts_video_counter++; 220 | break; 221 | case S3_HLS_Audio_PID: 222 | m_ts_audio_counter++; 223 | break; 224 | } 225 | 226 | return length; 227 | } 228 | 229 | /* 230 | * Call this function to set pid before write TS Header to buffer 231 | */ 232 | void S3_HLS_TS_Set_Pid(uint32_t pid) { 233 | ts_header[S3_HLS_TS_PID_HIGH_POS] |= (pid & S3_HLS_TS_PID_HEX_CODE) >> 8; 234 | ts_header[S3_HLS_TS_PID_LOW_POS] = (pid & 0xFF); 235 | } 236 | 237 | /* 238 | * Call this function to set payload start flag before write TS Header to buffer 239 | */ 240 | void S3_HLS_TS_Set_Payload_Start() { 241 | ts_header[S3_HLS_TS_PAYLOAD_START_POS] |= S3_HLS_TS_PAYLOAD_START_FLAG; 242 | } 243 | 244 | /* 245 | * Call this function to set random access flag before write TS Header to buffer 246 | */ 247 | void S3_HLS_TS_Set_Random_Access() { 248 | ts_header[S3_HLS_TS_ADOPTION_FLAG_POS] |= S3_HLS_TS_ADOPTION_FLAG; // random access need adoption part 249 | ts_header[S3_HLS_TS_RANDOM_ACCESS_FLAG_POS] |= S3_HLS_TS_RANDOM_ACCESS_FLAG; 250 | 251 | if(ts_header[S3_HLS_TS_PCR_FLAG_POS] & S3_HLS_TS_PCR_FLAG) { 252 | // also contains pcr 253 | ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] = 7; 254 | } else { 255 | // no pcr 256 | ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] = 1; 257 | } 258 | } 259 | 260 | /* 261 | * Call this function to set PCR flag and value before write TS Header to buffer 262 | */ 263 | void S3_HLS_TS_Set_PCR(uint64_t input_timestamp) { 264 | ts_header[S3_HLS_TS_ADOPTION_FLAG_POS] |= S3_HLS_TS_ADOPTION_FLAG; 265 | ts_header[S3_HLS_TS_PCR_FLAG_POS] |= S3_HLS_TS_PCR_FLAG; 266 | 267 | ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] = 7; 268 | 269 | uint64_t timestamp = input_timestamp / 100 * 9; // convert nanosecond based timestamp to 90K signal 270 | 271 | ts_header[S3_HLS_PCR_START_POS] = ((timestamp >> 25) & 0xFF); 272 | ts_header[S3_HLS_PCR_START_POS + 1] = ((timestamp >> 17) & 0xFF); 273 | ts_header[S3_HLS_PCR_START_POS + 2] = ((timestamp >> 9) & 0xFF); 274 | ts_header[S3_HLS_PCR_START_POS + 3] = ((timestamp >> 1) & 0xFF); 275 | ts_header[S3_HLS_PCR_START_POS + 4] = (timestamp << 7) | 0x7E; 276 | ts_header[S3_HLS_PCR_START_POS + 5] = 0; 277 | } 278 | 279 | /* 280 | * Call this function to fill adoption fields if data_length is less than remaining bytes. 281 | * Call this function before write TS Header to buffer and after set random access and pcr 282 | */ 283 | void S3_HLS_TS_Fill_Remaining_Length(uint32_t data_length) { 284 | TS_DEBUG("Input Data Length:%d\n", data_length); 285 | uint8_t length = 4; // base length 286 | if(ts_header[S3_HLS_TS_ADOPTION_FLAG_POS] & S3_HLS_TS_ADOPTION_FLAG) { 287 | TS_DEBUG("Has Adoption\n"); 288 | length ++; // do have adoption length field 289 | } 290 | 291 | if(ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] > 0) { 292 | TS_DEBUG("Adoption Length: %d\n", ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS]); 293 | length += ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS]; // do have adoption length 294 | } 295 | 296 | TS_DEBUG("Data + Header Length: %d\n", length + data_length); 297 | if(S3_HLS_TS_PACKET_SIZE > length + data_length) { 298 | // need to fill some part 299 | uint8_t gap = S3_HLS_TS_PACKET_SIZE - length - data_length; 300 | if(ts_header[S3_HLS_TS_ADOPTION_FLAG_POS] & S3_HLS_TS_ADOPTION_FLAG) { 301 | // already contains an adoption length field 302 | ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] += gap; 303 | } else { 304 | // need add an adoption length 305 | gap--; // due to need add adoption length so minus 1 306 | ts_header[S3_HLS_TS_ADOPTION_FLAG_POS] |= S3_HLS_TS_ADOPTION_FLAG; 307 | ts_header[S3_HLS_TS_ADOPTION_LENGTH_POS] = gap; 308 | if(gap > 0) { 309 | ts_header[S3_HLS_TS_RANDOM_ACCESS_FLAG_POS] = 0; // mark as no flags 310 | } 311 | } 312 | } 313 | } 314 | 315 | /* 316 | * Call this function to reset the counter field in ts header 317 | * need to think about mapping for different PID 318 | */ 319 | void S3_HLS_TS_Reset_Counter(uint32_t pid) { 320 | switch(pid) { 321 | case S3_HLS_Video_PID: 322 | m_ts_video_counter = 0; 323 | break; 324 | case S3_HLS_Audio_PID: 325 | m_ts_audio_counter = 0; 326 | break; 327 | } 328 | } -------------------------------------------------------------------------------- /demosite/static/js/main.c5c7f508.chunk.js: -------------------------------------------------------------------------------- 1 | (this["webpackJsonpip-camera-ui"]=this["webpackJsonpip-camera-ui"]||[]).push([[0],{170:function(e,t,a){},171:function(e,t,a){"use strict";a.r(t);var c=a(0),n=a.n(c),s=a(10),i=a.n(s),o=a(13),r=a(38),l=a(11),d=a(102),j=a.n(d),b=a(101),u=a.n(b),m=a(57),h=a(83),f=a.n(h),O=a(84),v=a.n(O),x=a(56),p=a.n(x),g=a(215),N=a(218),w=a(213),C=a(212),S=a(217),k=a(214),E=a(85),y=a.n(E),D=(a(138),a(2)),L=function(){return Object(D.jsx)("div",{className:"loading-style",children:Object(D.jsx)(y.a,{type:"ThreeDots",color:"#444444",height:50,width:50})})},T=a(49),P=a.n(T),I=a(86),A=a.n(I),z=P.a.create({baseURL:"https://sqmfgk98mf.execute-api.cn-northwest-1.amazonaws.com.cn/",headers:{"Content-Type":"application/json"}});z.interceptors.request.use((function(e){return e}),(function(e){return Promise.reject(e)})),z.interceptors.response.use((function(e){return console.info("response:",e),401===e.status||403===e.status?Promise.reject("401 User Unauthorized"):e?Promise.resolve(e):Promise.reject("response error")}),(function(e){var t,a,c,n,s,i;return console.info("ERR:",e.response),A.a.fire("".concat(e.message),"".concat(null===(t=e.response)||void 0===t||null===(a=t.config)||void 0===a?void 0:a.url," \n ").concat((null===(c=e.response)||void 0===c||null===(n=c.config)||void 0===n?void 0:n.params)?JSON.stringify(null===e||void 0===e||null===(s=e.response)||void 0===s||null===(i=s.config)||void 0===i?void 0:i.params):""),void 0),console.log("-- error --"),console.error(e),console.log("-- error --"),Promise.reject({success:!1,msg:e})}));var F,M,R=z,U=a(216),H=a(104),q=a(210),K=a(96),Q=a.n(K),V=a(87),J=a.n(V),W=a(97),Y=a.n(W),B=a(98),G=a.n(B),X=function(e){var t=e.breadcrumbList,a=e.pageName,n=Object(c.useState)(!1),s=Object(o.a)(n,2),i=s[0],r=s[1];return Object(D.jsxs)("div",{children:[Object(D.jsxs)("div",{className:"breadcrumb",children:[Object(D.jsx)("div",{className:"icon",children:Object(D.jsx)(J.a,{onClick:function(){r(!1)}})}),Object(D.jsx)("div",{className:"bread",children:Object(D.jsx)(U.a,{separator:Object(D.jsx)(Q.a,{fontSize:"small"}),maxItems:2,"aria-label":"breadcrumb",children:t.map((function(e,t){return e.isLink?Object(D.jsx)(q.a,{color:"inherit",href:e.href,onClick:function(){window.location.href=e.href?e.href:"/#/"},children:e.name},t):Object(D.jsx)(H.a,{color:"textPrimary",children:e.name},t)}))})}),Object(D.jsx)("div",{className:"icon",children:Object(D.jsx)(Y.a,{style:{transform:"rotate(180deg)"}})})]}),"(",i&&Object(D.jsxs)("div",{className:"side-menu",children:[Object(D.jsxs)("div",{className:"title",children:["\u667a\u80fd\u6444\u50cf\u5934\u6f14\u793a"," ",Object(D.jsx)("div",{onClick:function(){r(!1)},className:"close",children:Object(D.jsx)(G.a,{})})]}),Object(D.jsxs)("div",{className:"menu",children:[Object(D.jsx)("div",{children:Object(D.jsx)("a",{className:"DEVICE"===a?"active":"",href:"/#/",children:"\u8bbe\u5907\u7ba1\u7406"})}),Object(D.jsx)("div",{children:Object(D.jsx)("a",{className:"LIVE"===a?"active":"",href:"/#/live",children:"\u76f4\u64ad"})})]})]}),")"]})},Z=a(211),$=a(6),_=Object($.a)({root:{color:"#fff",boxShadow:"none",textTransform:"none",fontSize:14,fontWeight:"bold",padding:"5px 15px",border:"1px solid",backgroundColor:"#EC7211",borderColor:"#EC7211",borderRadius:0,"&:hover":{backgroundColor:"#EC7211",borderColor:"#EC7211",boxShadow:"none"},"&:active":{boxShadow:"none",backgroundColor:"#EC7211",borderColor:"#EC7211"},"&:focus":{boxShadow:"0 0 0 0.2rem rgba(213, 67, 5,.5)"}}})(Z.a),ee=a.p+"static/media/playbg.3be50ee9.png",te=function(){var e=Object(c.useState)({width:0,height:0}),t=Object(o.a)(e,2),a=t[0],n=t[1];return Object(c.useEffect)((function(){function e(){n({width:window.innerWidth,height:window.innerHeight})}return window.addEventListener("resize",e),e(),function(){return window.removeEventListener("resize",e)}}),[]),a},ae=a(43),ce=a.n(ae),ne=600,se=[{name:"\u6700\u8fd13\u5c0f\u65f6",value:10800},{name:"1\u5929\u5185",value:86400},{name:"2\u5929\u5185",value:172800},{name:"7\u5929",value:604800}],ie=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,c="yyyy-MM-DD HH:mm:ss";t&&(c="yyyy-MM-DDTHH:mm");var n=e;return n="string"===typeof e&&e.indexOf("T")<0?new Date(e.replace(/-/g,"/")):new Date(e),0!==a&&(n=n.setSeconds(new Date(n).getSeconds()+a)),ce()(new Date(n)).format(c)},oe=function(e,t){for(var a=[],c=ce()(e),n=ce()(t);c<=n;)a.push(ce()(c).format("YYYY-MM-DD HH:mm:ss")),c=ce()(c).add(ne,"seconds");return a},re=Object(C.a)((function(e){return Object(S.a)({container:{display:"flex",flexWrap:"wrap"},textField:{marginLeft:e.spacing(1),marginRight:e.spacing(1)}})}));!function(e){e.QUICK="quick",e.PRECISE="precise"}(F||(F={})),function(e){e.ALL="all",e.FACE="face"}(M||(M={}));var le=function(e){var t=re(),a=te(),n=e.match.params.id,s=Object(c.useState)([]),i=Object(o.a)(s,2),l=i[0],d=i[1],j=Object(c.useState)(M.ALL),b=Object(o.a)(j,2),u=b[0],h=b[1],O=Object(c.useState)(F.QUICK),x=Object(o.a)(O,2),C=x[0],S=x[1],E=Object(c.useState)(10800),y=Object(o.a)(E,2),T=y[0],P=y[1],I=Object(c.useState)(!1),A=Object(o.a)(I,2),z=A[0],U=A[1],H=Object(c.useState)(0),q=Object(o.a)(H,2),K=q[0],Q=q[1],V=Object(c.useState)(1),J=Object(o.a)(V,2),W=J[0],Y=J[1],B=Object(c.useState)(void 0),G=Object(o.a)(B,2),Z=G[0],$=G[1],ae=Object(c.useState)(!0),ce=Object(o.a)(ae,2),le=ce[0],de=ce[1],je=Object(c.useState)(""),be=Object(o.a)(je,2),ue=be[0],me=be[1],he=Object(c.useState)(ie(new Date,!0,-10800)),fe=Object(o.a)(he,2),Oe=fe[0],ve=fe[1],xe=Object(c.useState)(ie(new Date,!0)),pe=Object(o.a)(xe,2),ge=pe[0],Ne=pe[1],we=ie(new Date,!1,-28800),Ce=Object(c.useCallback)((function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0],t=we,a=T,c=ie(Oe,!1,-28800),s=ie(ge,!1,-28800);if(console.info("loadMore:",e),e){if(!1===le)return}else d([]),U(!0);var i={pageSize:12,type:C,camera:n,interval:ne,currentTime:t,trackTime:a,startTime:c,endTime:s,nextToken:!1===e||!1===le?void 0:Z};R.get("/snapshot?".concat(f.a.stringify(i,{encode:!1}))).then((function(t){U(!1),t.data.nextToken?de(!0):de(!1),e?($(t.data.nextToken),d((function(e){return[].concat(Object(m.a)(e),Object(m.a)(t.data.data))}))):d(t.data.data)})).catch((function(e){console.error(e),U(!1)}))}),[T,Oe,ge,C,le,Z]),Se=Object(c.useCallback)((function(){console.info("loadMoreAllVideoList"),console.info("buildDateStop:",ue);var e=ie(new Date,!1,-28800),t=ie(ue,!1,7200),a=t=e)de(!1);else{var c=oe(ue,a);console.info("loadMoreDateArr:",c);var n=[];c.forEach((function(e,t){t>0&&n.push({faces:"[]",imageData:"",time:e})})),d((function(e){return[].concat(Object(m.a)(e),n)}))}}),[ue]),ke=function(){var e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];if(!e){var t=ie(new Date,!1,-(T+28800)),a=ie(new Date,!1,6600-(T+28800));me(a);var c=oe(t,a),n=[];c.forEach((function(e){n.push({faces:"[]",imageData:"",time:e})})),d(n)}};return Object(c.useEffect)((function(){a.width>768?Q(Math.floor((a.width-100)/5)):Q(Math.floor((a.width-(80+.01*a.width))/3))}),[a]),Object(c.useEffect)((function(){Y(K/1920)}),[K]),Object(c.useEffect)((function(){console.info("videoType:",u),de(!0),$(void 0),d([]),u===M.FACE&&Ce(),u===M.ALL&&ke()}),[u]),Object(D.jsxs)("div",{children:[Object(D.jsx)(X,{breadcrumbList:[{isLink:!1,name:"\u5f55\u50cf\u5217\u8868"}]}),Object(D.jsxs)("div",{className:"content",children:[Object(D.jsxs)("div",{className:"page-title",children:["\u5f55\u50cf\u5217\u8868",Object(D.jsx)("div",{className:"back-button"})]}),Object(D.jsxs)("div",{children:[Object(D.jsx)("div",{className:"no-show",children:"\u9009\u62e9\u60a8\u9700\u8981\u7684\u5f55\u50cf\u7c7b\u578b"}),Object(D.jsx)("div",{className:"no-show",children:Object(D.jsxs)(N.a,{"aria-label":"gender",name:"gender1",value:u,onChange:function(e){h(e.target.value)},children:[Object(D.jsx)(w.a,{value:M.ALL,control:Object(D.jsx)(g.a,{size:"small",color:"primary"}),label:"\u6240\u6709\u5f55\u50cf"}),Object(D.jsx)(w.a,{value:M.FACE,control:Object(D.jsx)(g.a,{size:"small",color:"primary"}),label:"\u6240\u6709\u5305\u542b\u4eba\u8138\u7684\u5f55\u50cf"})]})}),Object(D.jsxs)("div",{children:[Object(D.jsxs)("div",{className:"search-tab",children:[Object(D.jsx)("span",{className:p()("tab",{active:C===F.QUICK}),onClick:function(){S(F.QUICK),u===M.FACE&&Ce()},children:"\u5feb\u901f\u67e5\u8be2"}),Object(D.jsx)("span",{className:p()("tab",{active:C===F.PRECISE}),onClick:function(){S(F.PRECISE),u===M.FACE&&Ce()},children:"\u7cbe\u786e\u67e5\u8be2"})]}),Object(D.jsxs)("div",{className:"search-tab-content",children:[C===F.QUICK&&Object(D.jsx)("div",{className:"quick-search-list",children:se.map((function(e,t){return Object(D.jsx)("div",{className:p()("quick-search-item",{active:T===e.value}),onClick:function(){de(!0),$(void 0),P(e.value)},children:e.name},t)}))}),C===F.PRECISE&&Object(D.jsxs)("div",{className:"precise-search",children:[Object(D.jsx)("div",{children:Object(D.jsx)(k.a,{size:"small",id:"datetime-local",label:"\u5f00\u59cb\u65f6\u95f4",type:"datetime-local",defaultValue:Oe,className:t.textField,onChange:function(e){ve(e.target.value)},InputProps:{inputProps:{max:ie(new Date(ge),!0)}},InputLabelProps:{shrink:!0}})}),Object(D.jsx)("div",{children:Object(D.jsx)(k.a,{size:"small",id:"datetime-local",label:"\u7ed3\u675f\u65f6\u95f4",type:"datetime-local",defaultValue:ge,className:t.textField,InputProps:{inputProps:{max:ie(new Date,!0)}},onChange:function(e){ve(e.target.value),Ne(e.target.value)},InputLabelProps:{shrink:!0}})})]}),Object(D.jsx)("div",{className:"search",children:Object(D.jsx)(_,{onClick:function(){u===M.FACE&&($(void 0),de(!0),Ce()),u===M.ALL&&ke()},children:"\u641c\u7d22\u8bb0\u5f55"})})]})]})]}),z?Object(D.jsx)("div",{className:"loading",children:Object(D.jsx)(L,{})}):Object(D.jsxs)("div",{className:"ipc-video-list",children:[Object(D.jsx)("div",{className:"result-info",children:"\u641c\u7d22\u7ed3\u679c\uff1a\u67e5\u8be2\u5230\u4ee5\u4e0b\u5f55\u50cf"}),Object(D.jsx)("div",{className:"videos",children:Object(D.jsx)(v.a,{className:"video-more",initialLoad:!1,loadMore:function(){console.info("load More"),u===M.FACE&&Ce(!0),u===M.ALL&&Se()},hasMore:!0,loader:le?Object(D.jsx)("div",{className:"loader",children:"\u52a0\u8f7d\u4e2d ..."},0):Object(D.jsx)("div",{style:{borderTop:"1px solid #eee"},className:"loader",children:"\u6211\u662f\u6709\u5e95\u7ebf\u7684"},1),children:l.map((function(e,t){return Object(D.jsx)("div",{className:"ipc-video",children:Object(D.jsxs)(r.b,{to:"/play/camera/".concat(e.time),children:[Object(D.jsxs)("div",{className:"image",children:[JSON.parse(e.faces).map((function(e,t){var a=(e[0]-20)*W,c=(e[1]-20)*W,n=(e[2]-e[0]+20)*W,s=(e[3]-e[1]+20)*W;return Object(D.jsx)("div",{className:"human",style:{left:a,top:c,width:n,height:s}},t)})),Object(D.jsx)("img",{width:"100%",src:e.imageData?"data:image/jpeg;base64,".concat(e.imageData):ee})]}),Object(D.jsx)("div",{className:"time",children:ie(e.time,!1,28800)})]})},t)}))})})]})]})]})},de=a(99),je=a.n(de),be=Object($.a)({root:{color:"#545b64",boxShadow:"none",textTransform:"none",fontSize:14,fontWeight:"bold",padding:"5px 15px",border:"1px solid",backgroundColor:"#ffffff",borderRadius:0,"&:hover":{backgroundColor:"#ffffff",borderColor:"#545b64",boxShadow:"none"},"&:active":{boxShadow:"none",backgroundColor:"#ffffff",borderColor:"#545b64"},"&:focus":{boxShadow:"0 0 0 0.2rem rgba(255, 255, 255,.5)"}}})(Z.a),ue=function(e){var t=Object(l.f)(),a=e.href,c=e.text;return Object(D.jsx)("div",{className:"back-to-list",children:Object(D.jsx)(be,{onClick:function(){var e=a;t.push({pathname:e})},children:c})})},me=n.a.createContext({address:""}),he=function(e){var t=e.match.params.time,a=ie(t,!1,ne),c=n.a.useContext(me);console.info("config:",c),console.log("newTime",a);var s=t,i=a;return Object(D.jsxs)("div",{children:[Object(D.jsx)(X,{breadcrumbList:[{isLink:!0,name:"\u5f55\u50cf\u5217\u8868",href:"/#/"},{isLink:!1,name:"\u5f55\u50cf\u56de\u653e"}]}),Object(D.jsxs)("div",{className:"content",children:[Object(D.jsxs)("div",{className:"page-title",children:["\u5f55\u50cf\u56de\u770b",Object(D.jsx)("div",{className:"back-button",children:Object(D.jsx)(ue,{href:"/",text:"\u8fd4\u56de\u5217\u8868"})})]}),Object(D.jsxs)("div",{className:"video-replay",children:[Object(D.jsxs)("div",{className:"time",children:[Object(D.jsx)("label",{children:"\u65f6\u95f4:"}),Object(D.jsx)("br",{})," ",ie(t,!1,28800)]}),Object(D.jsxs)("div",{className:"time",children:[Object(D.jsx)("label",{children:"\u65f6\u957f:"})," ",10," \u5206\u949f"]}),Object(D.jsx)(je.a,{autoPlay:!0,height:"auto",width:"100%",controls:!0,url:"".concat(c.address,"?start=").concat(s,"&end=").concat(i)})]})]})]})},fe=a.p+"static/media/logo.e2a890e1.svg",Oe=a(100),ve=a.n(Oe),xe=Object(l.g)((function(e){var t=e.history;return Object(c.useEffect)((function(){var e=t.listen((function(){window.scrollTo(0,0)}));return function(){e()}}),[]),null})),pe=function(){return Object(D.jsx)("div",{className:"App",children:Object(D.jsxs)("div",{className:"app-loading",children:[Object(D.jsx)(L,{}),"Data Transfer Hub is loading..."]})})},ge=function(){var e=Object(c.useState)(!0),t=Object(o.a)(e,2),a=t[0],n=t[1],s=Object(c.useState)({address:""}),i=Object(o.a)(s,2),d=i[0],b=i[1];return Object(c.useEffect)((function(){n(!0);var e=(new Date).getTime();P.a.get("/aws-exports.json?timeStamp="+e).then((function(e){n(!1),b(e.data)}))}),[]),a?Object(D.jsx)(pe,{}):Object(D.jsx)(me.Provider,{value:d,children:Object(D.jsxs)("div",{className:"App",children:[Object(D.jsxs)("div",{className:"ipc-header",children:[Object(D.jsxs)("div",{className:"logo",children:[Object(D.jsx)("img",{width:"20",src:fe}),"\u667a\u80fd\u6444\u50cf\u5934\u6f14\u793a"]}),Object(D.jsx)("div",{className:"user",children:Object(D.jsx)(ve.a,{fontSize:"small"})}),Object(D.jsx)("div",{className:"user",children:"User"})]}),Object(D.jsx)("div",{className:"ipc-body",children:Object(D.jsxs)(r.a,{children:[Object(D.jsx)(xe,{}),Object(D.jsxs)(l.c,{children:[Object(D.jsx)(l.a,{exact:!0,path:"/",component:le}),Object(D.jsx)(l.a,{exact:!0,path:"/play/:id/:time",component:he})]})]})}),Object(D.jsxs)("div",{className:"ipc-footer",children:[Object(D.jsxs)("div",{className:"item",children:[Object(D.jsx)(u.a,{fontSize:"small",className:"icon"}),"Feedback"]}),Object(D.jsxs)("div",{className:"item",children:[Object(D.jsx)(j.a,{fontSize:"small",className:"icon"}),"\u7b80\u4f53\u4e2d\u6587"]})]})]})})},Ne=function(e){e&&e instanceof Function&&a.e(3).then(a.bind(null,220)).then((function(t){var a=t.getCLS,c=t.getFID,n=t.getFCP,s=t.getLCP,i=t.getTTFB;a(e),c(e),n(e),s(e),i(e)}))};a(170);i.a.render(Object(D.jsx)(n.a.StrictMode,{children:Object(D.jsx)(ge,{})}),document.getElementById("root")),Ne()}},[[171,1,2]]]); 2 | //# sourceMappingURL=main.c5c7f508.chunk.js.map -------------------------------------------------------------------------------- /S3_HLS_Pes.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 3 | * SPDX-License-Identifier: MIT-0 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this 6 | * software and associated documentation files (the "Software"), to deal in the Software 7 | * without restriction, including without limitation the rights to use, copy, modify, 8 | * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 9 | * permit persons to whom the Software is furnished to do so. 10 | * 11 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 12 | * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 13 | * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 14 | * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 15 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 16 | * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 17 | */ 18 | 19 | /* 20 | *buffer++ = 0; // 3 bytes start code 21 | *buffer++ = 0; 22 | *buffer++ = 1; 23 | *buffer++ = 0xe0; // stream id for video is 0xe0, audio would be 0xc0 24 | *buffer++ = 0; // 2 bytes packet length 25 | *buffer++ = 0; 26 | *buffer++ = 0x80; // 0b10 + 6 bits flags PTS exists but no DTS 27 | *buffer++ = 0x80; // indicate have pts and no dts 28 | *buffer++ = 0x05; 29 | 30 | // write pts 31 | *buffer++ = 0x21 | ((m_pts_timestamp >> 29) & 0x0e); 32 | *buffer++ = (m_pts_timestamp >> 22) & 0xff; 33 | *buffer++ = 0x01 | ((m_pts_timestamp >> 14) & 0xfe); 34 | *buffer++ = (m_pts_timestamp >> 7) & 0xff; 35 | *buffer++ = 0x01 | (m_pts_timestamp & 0xfe); 36 | 37 | // means sequence end 38 | *buffer++ = 0; 39 | *buffer++ = 0; 40 | *buffer++ = 0; 41 | *buffer++ = 1; 42 | 43 | *buffer++ = 0x09; 44 | *buffer++ = 0xf0; 45 | */ 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | 52 | #include "S3_HLS_Pes.h" 53 | #include "S3_HLS_Return_Code.h" 54 | #include "S3_HLS_H264_Nalu_Types.h" 55 | 56 | #include "S3_HLS_Pat.h" 57 | #include "S3_HLS_Pmt.h" 58 | #include "S3_HLS_TS.h" 59 | 60 | //#define S3_HLS_PES_DEBUG 61 | 62 | #ifdef S3_HLS_PES_DEBUG 63 | #define PES_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 64 | #else 65 | #define PES_DEBUG(x, ...) 66 | #endif 67 | 68 | // #define S3_HLS_PES_AUDIO_DEBUG 69 | 70 | #ifdef S3_HLS_PES_AUDIO_DEBUG 71 | #define AUDIO_DEBUG(x, ...) printf(x, ##__VA_ARGS__) 72 | #else 73 | #define AUDIO_DEBUG(x, ...) 74 | #endif 75 | 76 | #define S3_HLS_PES_PTS_START 9 77 | 78 | #define S3_HLS_FALSE 0 79 | #define S3_HLS_TRUE 1 80 | 81 | #define S3_HLS_PES_VIDEO_CODE 0xe0 82 | #define S3_HLS_PES_AUDIO_CODE 0xc0 83 | 84 | static uint8_t video_pes_header[20] = { 0x00, 0x00, 0x01, /* 3 bytes start code of PES */ 85 | 0xe0, /* Stream type (0xc0) */ 86 | 0x00, 0x00, /* Packet Length, 0x00, 0x00 for video, data length for audio*/ 87 | 0x80, 0x80, /* PTS, DTS flags*/ 88 | 0x05, /* PES Header Data Length 5 for 5 bytes of PTS */ 89 | 0x00, 0x00, 0x00, 0x00, 0x00, /* PTS field */ 90 | // below only for video 91 | 0x00, 0x00, 0x00, 0x01, /* H264 Start Code */ 92 | 0x09, 0xF0 /* H264 Sequence End */ 93 | }; 94 | 95 | static uint8_t audio_pes_header[14] = { 0x00, 0x00, 0x01, /* 3 bytes start code of PES */ 96 | 0xe0, /* Stream type (0xc0) */ 97 | 0x00, 0x00, /* Packet Length, 0x00, 0x00 for video, data length for audio*/ 98 | 0x80, 0x80, /* PTS, DTS flags*/ 99 | 0x05, /* PES Header Data Length 5 for 5 bytes of PTS */ 100 | 0x00, 0x00, 0x00, 0x00, 0x00 /* PTS field */ 101 | }; 102 | 103 | // every 2 video frame packs may need increase if < 20 FPS 104 | static uint8_t pcr_count = 0; 105 | static const uint8_t pcr_count_interval = 2; 106 | 107 | // every 3 video frame packs 108 | static uint8_t pat_pmt_count = 0; 109 | static const uint8_t pat_pmt_interval = 3; 110 | 111 | // may need to modify according to 112 | static S3_HLS_H264E_NALU_TYPE_E seperate_nalu_type = S3_HLS_H264E_NALU_SPS; 113 | 114 | static uint8_t seperate_count = 0; 115 | static const uint8_t seperate_count_interval = 1; 116 | 117 | static uint8_t first_call = 1; 118 | 119 | static uint8_t has_error = 0; 120 | 121 | int32_t S3_HLS_Pes_Write_Video_Pes(S3_HLS_BUFFER_CTX* buffer_ctx, uint64_t input_timestamp) { 122 | uint64_t timestamp = input_timestamp / 100 * 9 + 63000; 123 | 124 | video_pes_header[9] = 0x21 | ((timestamp >> 29) & 0x0e); 125 | video_pes_header[10] = (timestamp >> 22) & 0xff; 126 | video_pes_header[11] = 0x01 | ((timestamp >> 14) & 0xfe); 127 | video_pes_header[12] = (timestamp >> 7) & 0xff; 128 | video_pes_header[13] = 0x01 | (timestamp & 0xfe); 129 | 130 | return S3_HLS_Put_To_Buffer(buffer_ctx, video_pes_header, sizeof(video_pes_header)); 131 | } 132 | 133 | int32_t S3_HLS_Pes_Write_Audio_Pes(S3_HLS_BUFFER_CTX* buffer_ctx, uint64_t input_timestamp, uint32_t packet_length) { 134 | packet_length += sizeof(audio_pes_header) - 6; 135 | 136 | audio_pes_header[4] = ((packet_length >> 8) & 0xFF); 137 | audio_pes_header[5] = (packet_length & 0xFF); 138 | 139 | uint64_t timestamp = input_timestamp / 100 * 9 + 63000; 140 | 141 | audio_pes_header[9] = 0x21 | ((timestamp >> 29) & 0x0e); 142 | audio_pes_header[10] = (timestamp >> 22) & 0xff; 143 | audio_pes_header[11] = 0x01 | ((timestamp >> 14) & 0xfe); 144 | audio_pes_header[12] = (timestamp >> 7) & 0xff; 145 | audio_pes_header[13] = 0x01 | (timestamp & 0xfe); 146 | 147 | return S3_HLS_Put_To_Buffer(buffer_ctx, audio_pes_header, sizeof(audio_pes_header)); 148 | } 149 | 150 | int32_t S3_HLS_Pes_Write_Video_Frame(S3_HLS_BUFFER_CTX* buffer_ctx, S3_HLS_FRAME_PACK* pack) { 151 | int32_t ret = S3_HLS_OK; 152 | 153 | uint8_t random_access = S3_HLS_FALSE; 154 | uint8_t has_pcr = S3_HLS_FALSE; 155 | uint32_t content_length = 0; 156 | 157 | if(0 == pack->item_count) { 158 | PES_DEBUG("[Pes - Video] Invalid Packet Count!\n"); 159 | return S3_HLS_INVALID_PARAMETER; 160 | } 161 | 162 | if (0 != S3_HLS_Lock_Buffer(buffer_ctx)) {// lock failed 163 | PES_DEBUG("[Pes - Video] Lock Buffer Failed!\n"); 164 | return S3_HLS_LOCK_FAILED; 165 | } 166 | 167 | if(first_call) { 168 | PES_DEBUG("[Pes - Video] First Call Flush Buffer!\n"); 169 | S3_HLS_Flush_Buffer(buffer_ctx); // only update last timestamp 170 | first_call = 0; 171 | } 172 | 173 | for(uint32_t cnt = 0; cnt < pack->item_count; cnt++) { 174 | if(NULL == pack->items[cnt].first_part_start || (NULL == pack->items[cnt].second_part_start && pack->items[cnt].second_part_length != 0)) { 175 | ret = S3_HLS_INVALID_PARAMETER; 176 | goto l_exit; 177 | } 178 | 179 | S3_HLS_H264E_NALU_TYPE_E frame_type = S3_HLS_H264_Nalu_Type(&pack->items[cnt]); 180 | if(seperate_nalu_type == frame_type) { 181 | PES_DEBUG("[Pes - Video] Nalu: %d\n", frame_type); 182 | if(seperate_count_interval == seperate_count) { 183 | PES_DEBUG("[Pes - Video] Need Seperate\n"); 184 | has_error = 0; 185 | ret = S3_HLS_Flush_Buffer(buffer_ctx); 186 | if(0 > ret) { 187 | PES_DEBUG("[Pes - Video] Flush Buffer Failed!\n"); 188 | goto l_exit; 189 | } 190 | 191 | seperate_count = 0; 192 | pat_pmt_count = 0; 193 | } 194 | 195 | seperate_count++; 196 | } 197 | 198 | if(S3_HLS_H264E_NALU_IDR == frame_type) { 199 | random_access = S3_HLS_TRUE; 200 | } 201 | 202 | content_length += pack->items[cnt].first_part_length + pack->items[cnt].second_part_length; 203 | } 204 | 205 | PES_DEBUG("[Pes - Video] Video Stream Length %d\n", content_length); 206 | if(has_error) { 207 | PES_DEBUG("[pes - Video] Prev error detected, skip until next sperate frame!\n"); 208 | goto l_exit; 209 | } 210 | content_length += sizeof(video_pes_header); // calculate total length 211 | 212 | // decide whether write pat & pmt 213 | if(0 == pat_pmt_count) { 214 | ret = S3_HLS_H264_PAT_Write_To_Buffer(buffer_ctx); 215 | if(0 > ret) { 216 | has_error = 1; 217 | PES_DEBUG("[Pes - Video] Write PAT Failed!\n"); 218 | goto l_exit; 219 | } 220 | 221 | ret = S3_HLS_H264_PMT_Write_To_Buffer(buffer_ctx); 222 | if(0 > ret) { 223 | has_error = 1; 224 | PES_DEBUG("[Pes - Video] Write PAT Failed!\n"); 225 | goto l_exit; 226 | } 227 | } 228 | 229 | // update counter 230 | pat_pmt_count++; 231 | if(pat_pmt_interval == pat_pmt_count) { 232 | pat_pmt_count = 0; 233 | } 234 | 235 | if(0 == pcr_count) { 236 | has_pcr = S3_HLS_TRUE; 237 | pcr_count++; 238 | if(pcr_count_interval == pcr_count) { 239 | pcr_count = 0; 240 | } 241 | } 242 | 243 | S3_HLS_TS_Set_Pid(S3_HLS_Video_PID); 244 | 245 | S3_HLS_TS_Set_Payload_Start(); 246 | 247 | if(random_access) { 248 | S3_HLS_TS_Set_Random_Access(); 249 | } 250 | 251 | if(has_pcr) { 252 | S3_HLS_TS_Set_PCR(pack->items[0].timestamp); 253 | } 254 | 255 | S3_HLS_TS_Fill_Remaining_Length(content_length); 256 | 257 | PES_DEBUG("[Pes - Video] Write TS Header %d\n", content_length); 258 | // write TS header 259 | ret = S3_HLS_TS_Write_To_Buffer(buffer_ctx); 260 | 261 | if(0 > ret) { // write error 262 | has_error = 1; 263 | goto l_exit; 264 | } 265 | 266 | uint32_t remaining = S3_HLS_TS_PACKET_SIZE - ret; 267 | PES_DEBUG("[Pes - Video] Remaining Size %d\n", remaining); 268 | 269 | // write PES info 270 | ret = S3_HLS_Pes_Write_Video_Pes(buffer_ctx, pack->items[0].timestamp); 271 | if(0 > ret) { 272 | has_error = 1; 273 | goto l_exit; 274 | } 275 | 276 | remaining -= ret; 277 | content_length -= ret; 278 | 279 | uint32_t packet_index = 0; 280 | uint32_t packet_pos = 0; 281 | 282 | while(content_length > 0) { // have data to send 283 | PES_DEBUG("[Pes - Video] Remaining Size %d Content Length %d\n", remaining, content_length); 284 | if(0 == remaining) { // start new ts header 285 | PES_DEBUG("[Pes - Video] Start New TS Fragment\n"); 286 | S3_HLS_TS_Set_Pid(S3_HLS_Video_PID); 287 | S3_HLS_TS_Fill_Remaining_Length(content_length); 288 | ret = S3_HLS_TS_Write_To_Buffer(buffer_ctx); 289 | PES_DEBUG("[Pes - Video] TS Header used %d\n", ret); 290 | if(0 > ret) { 291 | has_error = 1; 292 | goto l_exit; 293 | } 294 | 295 | remaining = S3_HLS_TS_PACKET_SIZE - ret; 296 | } 297 | 298 | if(remaining > 0) { 299 | // write data to buffer 300 | uint8_t* start_pos; 301 | uint32_t write_length; 302 | 303 | if(packet_pos >= pack->items[packet_index].first_part_length) { // writing second part 304 | // need to copy from second part 305 | start_pos = pack->items[packet_index].second_part_start + (packet_pos - pack->items[packet_index].first_part_length); 306 | write_length = remaining < (pack->items[packet_index].first_part_length + pack->items[packet_index].second_part_length - packet_pos) ? remaining : (pack->items[packet_index].first_part_length + pack->items[packet_index].second_part_length - packet_pos); 307 | PES_DEBUG("Write From Second Part %d, %d, %d, %d, %d\n", remaining, write_length, pack->items[packet_index].first_part_length, pack->items[packet_index].second_part_length, packet_pos); 308 | } else { // writing first part 309 | start_pos = pack->items[packet_index].first_part_start + packet_pos; 310 | write_length = remaining < (pack->items[packet_index].first_part_length - packet_pos) ? remaining : (pack->items[packet_index].first_part_length - packet_pos); 311 | PES_DEBUG("Write From First Part %d, %d, %d, %d\n", remaining, write_length, pack->items[packet_index].first_part_length, packet_pos); 312 | } 313 | 314 | ret = S3_HLS_Put_To_Buffer(buffer_ctx, start_pos, write_length); 315 | PES_DEBUG("Write Buffer Ret %d\n", ret); 316 | 317 | if(0 > ret) { 318 | has_error = 1; 319 | goto l_exit; 320 | } 321 | 322 | content_length -= write_length; 323 | remaining -= write_length; 324 | 325 | packet_pos += write_length; 326 | 327 | PES_DEBUG("[Pes - Video] After Put: Remaining Size %d Content Length %d Packet Pos %d\n", remaining, content_length, packet_pos); 328 | 329 | if(packet_pos == pack->items[packet_index].first_part_length + pack->items[packet_index].second_part_length) { 330 | PES_DEBUG("Goto Next Packet Remaining: %d\n", remaining); 331 | packet_index++; 332 | packet_pos = 0; 333 | } 334 | } 335 | } 336 | 337 | S3_HLS_Unlock_Buffer(buffer_ctx); 338 | 339 | return S3_HLS_OK; 340 | 341 | l_exit: 342 | S3_HLS_Unlock_Buffer(buffer_ctx); 343 | 344 | return ret; 345 | } 346 | 347 | int32_t S3_HLS_Pes_Write_Audio_Frame(S3_HLS_BUFFER_CTX* buffer_ctx, S3_HLS_FRAME_PACK* pack) { 348 | int32_t ret = S3_HLS_OK; 349 | 350 | uint32_t content_length = 0; 351 | 352 | AUDIO_DEBUG("[Pes - Audio] Check Cnt\n"); 353 | if(0 == pack->item_count) { 354 | return S3_HLS_INVALID_PARAMETER; 355 | } 356 | 357 | AUDIO_DEBUG("[Pes - Audio] Try Lock\n"); 358 | if (0 != S3_HLS_Lock_Buffer(buffer_ctx)) // lock failed 359 | return S3_HLS_LOCK_FAILED; 360 | 361 | AUDIO_DEBUG("[Pes - Audio] Locked\n"); 362 | for(uint32_t cnt = 0; cnt < pack->item_count; cnt++) { 363 | AUDIO_DEBUG("[Pes - Audio] Packet Item %d, %d, %d\n", pack->item_count, pack->items[cnt].first_part_length, pack->items[cnt].second_part_length); 364 | if(NULL == pack->items[cnt].first_part_start || (NULL == pack->items[cnt].second_part_start && pack->items[cnt].second_part_length != 0)) { 365 | ret = S3_HLS_INVALID_PARAMETER; 366 | goto l_exit; 367 | } 368 | 369 | content_length += pack->items[cnt].first_part_length + pack->items[cnt].second_part_length; 370 | } 371 | 372 | content_length += sizeof(audio_pes_header); // calculate total length 373 | 374 | AUDIO_DEBUG("[Pes - Audio] Total Length: %d\n", content_length); 375 | if(has_error) { 376 | AUDIO_DEBUG("[Pes - Audio] Prev error detected, skip until next sperate frame!\n"); 377 | goto l_exit; 378 | } 379 | 380 | S3_HLS_TS_Set_Pid(S3_HLS_Audio_PID); 381 | 382 | S3_HLS_TS_Set_Payload_Start(); 383 | 384 | S3_HLS_TS_Set_Random_Access(); 385 | 386 | S3_HLS_TS_Fill_Remaining_Length(content_length); 387 | 388 | AUDIO_DEBUG("[Pes - Audio] Write TS Header\n"); 389 | // write TS header 390 | ret = S3_HLS_TS_Write_To_Buffer(buffer_ctx); 391 | 392 | if(0 > ret) { // write error 393 | AUDIO_DEBUG("[Pes - Audio] Write Buffer Failed! %d\n", ret); 394 | goto l_exit; 395 | } 396 | 397 | uint32_t remaining = S3_HLS_TS_PACKET_SIZE - ret; 398 | 399 | AUDIO_DEBUG("[Pes - Audio] Write Audio PES Header, Remaining: %d\n", remaining); 400 | // write PES info 401 | ret = S3_HLS_Pes_Write_Audio_Pes(buffer_ctx, pack->items[0].timestamp, content_length - sizeof(audio_pes_header)); 402 | if(0 > ret) { 403 | has_error = 1; 404 | goto l_exit; 405 | } 406 | 407 | remaining -= ret; 408 | content_length -= ret; 409 | 410 | uint32_t packet_index = 0; 411 | uint32_t packet_pos = 0; 412 | 413 | AUDIO_DEBUG("[Pes - Audio] Write Audio Content\n"); 414 | while(content_length > 0) { // have data to send 415 | AUDIO_DEBUG("[Pes - Audio] Remaining Size %d Content Length %d\n", remaining, content_length); 416 | if(0 == remaining) { 417 | S3_HLS_TS_Set_Pid(S3_HLS_Audio_PID); 418 | S3_HLS_TS_Fill_Remaining_Length(content_length); 419 | ret = S3_HLS_TS_Write_To_Buffer(buffer_ctx); 420 | if(0 > ret) { 421 | has_error = 1; 422 | AUDIO_DEBUG("[Pes - Audio] Write Buffer Failed 2! %d\n", ret); 423 | goto l_exit; 424 | } 425 | 426 | remaining = S3_HLS_TS_PACKET_SIZE - ret; 427 | } 428 | 429 | if(remaining > 0) { 430 | // write data to buffer 431 | uint8_t* start_pos; 432 | uint32_t write_length; 433 | 434 | if(packet_pos >= pack->items[packet_index].first_part_length) { // writing second part 435 | // need to copy from second part 436 | start_pos = pack->items[packet_index].second_part_start + (packet_pos - pack->items[packet_index].first_part_length); 437 | write_length = remaining < (pack->items[packet_index].first_part_length + pack->items[packet_index].second_part_length - packet_pos) ? remaining : (pack->items[packet_index].first_part_length + pack->items[packet_index].second_part_length - packet_pos); 438 | } else { // writing first part 439 | start_pos = pack->items[packet_index].first_part_start + packet_pos; 440 | write_length = remaining < (pack->items[packet_index].first_part_length - packet_pos) ? remaining : (pack->items[packet_index].first_part_length - packet_pos); 441 | } 442 | 443 | ret = S3_HLS_Put_To_Buffer(buffer_ctx, start_pos, write_length); 444 | 445 | if(0 > ret) { 446 | has_error = 1; 447 | AUDIO_DEBUG("[Pes - Audio] Write Buffer Failed 3! %d\n", ret); 448 | goto l_exit; 449 | } 450 | 451 | content_length -= write_length; 452 | remaining -= write_length; 453 | 454 | packet_pos += write_length; 455 | 456 | if(packet_pos == pack->items[packet_index].first_part_length + pack->items[packet_index].second_part_length) { 457 | packet_index++; 458 | packet_pos = 0; 459 | } 460 | } 461 | } 462 | 463 | S3_HLS_Unlock_Buffer(buffer_ctx); 464 | return S3_HLS_OK; 465 | 466 | l_exit: 467 | S3_HLS_Unlock_Buffer(buffer_ctx); 468 | return ret; 469 | } 470 | --------------------------------------------------------------------------------