{"id":13908210,"url":"https://github.com/SimpleSSAI/SimpleSSAI","last_synced_at":"2025-07-18T07:30:38.755Z","repository":{"id":218439644,"uuid":"499365289","full_name":"SimpleSSAI/SimpleSSAI","owner":"SimpleSSAI","description":"Simple API-driven Server Side Ad Insertion(SSAI). An easy to use solution for stitching Ads into content to protect ad monitization","archived":false,"fork":false,"pushed_at":"2022-09-09T15:12:50.000Z","size":11,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-11-25T17:45:57.594Z","etag":null,"topics":["ad-insertion","hls","hls-live-streaming","server-side-ad-insertion","ssai","vast","video-streaming","vmap"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SimpleSSAI.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-03T03:18:09.000Z","updated_at":"2024-08-22T16:44:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"2338c67a-c9dd-40a5-a8b9-6a3561f6da81","html_url":"https://github.com/SimpleSSAI/SimpleSSAI","commit_stats":null,"previous_names":["simplessai/simplessai"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/SimpleSSAI/SimpleSSAI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimpleSSAI%2FSimpleSSAI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimpleSSAI%2FSimpleSSAI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimpleSSAI%2FSimpleSSAI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimpleSSAI%2FSimpleSSAI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SimpleSSAI","download_url":"https://codeload.github.com/SimpleSSAI/SimpleSSAI/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SimpleSSAI%2FSimpleSSAI/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265720356,"owners_count":23817214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ad-insertion","hls","hls-live-streaming","server-side-ad-insertion","ssai","vast","video-streaming","vmap"],"created_at":"2024-08-06T23:02:33.045Z","updated_at":"2025-07-18T07:30:38.740Z","avatar_url":"https://github.com/SimpleSSAI.png","language":null,"funding_links":[],"categories":["HarmonyOS","Media Tools"],"sub_categories":["Windows Manager","Ads \u0026 QoE"],"readme":"\n# SimpleSSAI (beta)\n\nAPI-driven Server Side Ad Insertion\n\n## About\n\nSimpleSSAI provides Ad Stitching for VoD assets by calling an API and providing your source stream and Ad Server URL. Currently, we only handle the Ad Stitching piece, and not the Ad/Content transcoding(well, at least not yet )\n\nCurrent ABR Streaming format support:\n - [x] HLS VoD\n - [ ] HLS VoD-To-Live w/ Channel Assembly (In Development)\n - [ ] HLS Live/Event Linear (Planned)\n - [ ] DASH VoD (Planned)\n - [ ] DASH Live (Planned)\n\n## Content Conditions \u0026 Preparation\nIn order for Ad insertion to work for HLS, all Ads need to be encoded with the same encoding configuration used for main content - This is to allow for playlist alignment. This means using the same Encoding Ladder including resolutions/aspect-ratios, codecs, container types ,etc.\n\n### SSAI HLS Packaging \u0026 Encoding:\nThe Ads and Main Content HLS Playlists should align - including:\n - **Video Variants** -\u003e Ideally should have bitrates, codecs, codec profiles, resolutions\n - **Audio Media Playlists** -\u003e (if using demuxed A/V) including same GROUP-ID, LANGUAGE, and NAME\n - **Subtitle Media Playlists** -\u003e (if using) including same GROUP-ID, LANGUAGE,  and NAME\n - **I-FRAME Only Playlists** -\u003e (if using)\n \nGenerally, using the same Encoder \u0026 Packager w/ the same configuration for both Main Content and Ads is recommended.\n\n### SSAI Conditioning:\nAd segments are always stitched into the main content's Playlists at segment boundaries - it is not possible to stitch Ads within a segment. Therefore, when encoding your content assets, be sure to insert additional Keyframes with segment splits at all Ad opportunity time boundaries. For example, take a look at this Encoding script example from the Bitmovin Encoder -\u003e [Bitmovin SSAI Conditions Example](https://github.com/bitmovin/bitmovin-api-sdk-examples/blob/main/javascript/src/ServerSideAdInsertion.ts). In this encoding script, additional Keyframes w/ segment splits are inserted at each time point of an Ad Opportunity. This is not an absolute requirement, but if not done, the SimpleSSAI stitcher will only be able insert Ad Segments at the closest segment boundary to provided AdBreak start time - and most likely not be exact. For the best accuracy in stitching Ads, HLS SpliceInfo Markers(`#EXT-X-CUE-OUT` and `#EXT-X-CUE-IN`) should be inserted at the Ad segment boundaries from the contribution encoder/packager.\n\n### Ad Serving:\nThe Ad Decision Server should serve Ads in the form of VMAP responses that include Ad Breaks at desired `timeOffsets`. The Ad Breaks should be presented as VAST tags and each VAST document should contain a `MediaFile` that has a delivery type of `streaming` which links the URL of the HLS packaged Ad. This Ad, as described in the above *SSAI HLS Packaging \u0026 Encoding* section, should be encoded in the same manner as the content including the Encoding Bitrate Ladder, Audio Variants, Subtitle Variants, etc..  Ad Serving best practices:\n - VMAPs are most efficient when using InLine(`\u003cInLine\u003e`) VAST tags for the Ad Breaks.\n\t - Wrapper/VASTAdTagURI are allowed but significantly increase response time.\n\t - Max number of allowed `\u003cWrapper\u003e` redirects is 7\n - Ads must have a corresponding MediaFile(`\u003cMediaFile\u003e`) with a **delivery** value of streaming\n\t - For HLS packaged Ads, the MediaFile's **type** should be \"application/x-mpegURL\"\n\t - Ads without the above delivery and type attributes will be discarded from the AdBreak sequence\n - AdPods and Buffet Ads are allowed. Buffet Ads are encouraged and used as fallback Ads.\n\n### Examples:\nVMAP with InLine AdBreaks carrying HLS Streaming Ads -\u003e https://slightly-private.s3.amazonaws.com/test_assets/vmap_inline.xml\nHLS Packaged Asset -\u003e https://slightly-private.s3.amazonaws.com/SimpleSSAI_Content/2022-05-16T02%3A56%3A25.837Z/manifest.m3u8\n\nAPI:\nEndpoint: POST https://2ddkncp0bh.execute-api.us-east-2.amazonaws.com/Stage/hls\nJSON Payload:\n - **hls_stream**: Stream URL for main content\n - **account_id**: UUID of the requesting Account. \n - **strategy**: Segment insertion strategy Can be either `scteCue` or `closest`. Default is `closest`.\n\t - `scteCue`: Most accurate. Combines using time from VMAP startOffset along with usage of `#EXT-X-CUE-OUT` and `#EXT-X-CUE-IN` HLS tags being present at Ad Boundaries in all Video variants and Audio/Subtitles MEDIAs\n\t - `closest`: Uses closest segment boundary to given VMAP startOffset\n - **vmap_url**: Ad Decision Server URL that will return VMAP for the session.\n - **replaceContentDuration**: boolean `true` or `false` for whether or not main content segments should be replaced with Ad segments - instead of just inserted. Default is `false`\n\nFor testing your Streams/Ads/VMAPs, please use the below sample account_id. While testing, if you come across any issues, please fill out a GitHub Issue. Streams can encoded and packaged in many different ways, and it is very possible we have not yet taken into account all possibilities.\n\n#### Request: POST: https://2ddkncp0bh.execute-api.us-east-2.amazonaws.com/Stage/hls\n```\n{\n\t\"hls_stream\": \"https://slightly-private.s3.amazonaws.com/SimpleSSAI_Content/2022-05-16T02%3A56%3A25.837Z/manifest.m3u8\",\n\t\"account_id\": \"a84e3714-d96d-461c-90f5-0a888dc47cd4\",\n\t\"strategy\": \"scteCue\",\n\t\"vmap_url\": \"https://slightly-private.s3.amazonaws.com/test_assets/vmap_inline.xml\",\n\t\"replaceContentDuration\":false\n}\n```\n#### Response:\n```\n{\n\t\"status\": \u003csuccessful|failed\u003e,\n\t\"manifest\": \u003cCloudFront hosted Manifest URL\u003e,\n\t\"vmapFetchTime\": 0.250,\n\t\"sessionExpiry\": null,\n\t\"adBreaks\": [\n        {\n            \"adBreakId\": \"preroll\",\n            \"startOffset\": 0,\n            \"duration\": 61.04,\n            \"endOffset\": 61.04,\n            \"stitchedAds\": [\n                {\n                    \"adId\": \"30001\",\n                    \"adDuration\": 15.16,\n                    \"adStartOffset\": 0,\n                    \"endOffset\": 15.16\n                },\n                {\n                    \"adId\": \"20002\",\n                    \"adDuration\": 15.120000000000001,\n                    \"adStartOffset\": 15.16,\n                    \"endOffset\": 30.28\n                },\n                {\n                    \"adId\": \"20004\",\n                    \"adDuration\": 30.76,\n                    \"adStartOffset\": 30.28,\n                    \"endOffset\": 61.040000000000006\n                }\n            ]\n        },\n        {\n            \"adBreakId\": \"midroll-1\",\n            \"startOffset\": 241.92,\n            \"duration\": 61.04,\n            \"endOffset\": 302.96,\n            \"stitchedAds\": [\n                {\n                    \"adId\": \"30001\",\n                    \"adDuration\": 15.16,\n                    \"adStartOffset\": 241.92,\n                    \"endOffset\": 257.08\n                },\n                {\n                    \"adId\": \"20002\",\n                    \"adDuration\": 15.120000000000001,\n                    \"adStartOffset\": 257.08,\n                    \"endOffset\": 272.2\n                },\n                {\n                    \"adId\": \"20004\",\n                    \"adDuration\": 30.76,\n                    \"adStartOffset\": 272.2,\n                    \"endOffset\": 302.96\n                }\n            ]\n        },\n        {\n            \"adBreakId\": \"postroll\",\n            \"startOffset\": 1010.0799999999999,\n            \"duration\": 61.04,\n            \"endOffset\": 1071.12,\n            \"stitchedAds\": [\n                {\n                    \"adId\": \"30001\",\n                    \"adDuration\": 15.16,\n                    \"adStartOffset\": 1010.0799999999999,\n                    \"endOffset\": 1025.24\n                },\n                {\n                    \"adId\": \"20002\",\n                    \"adDuration\": 15.120000000000001,\n                    \"adStartOffset\": 1025.24,\n                    \"endOffset\": 1040.36\n                },\n                {\n                    \"adId\": \"20004\",\n                    \"adDuration\": 30.76,\n                    \"adStartOffset\": 1040.36,\n                    \"endOffset\": 1071.12\n                }\n            ]\n        }\n    ],\n\t\"errors\": [],\n\t\"warnings\": []\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSimpleSSAI%2FSimpleSSAI","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSimpleSSAI%2FSimpleSSAI","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSimpleSSAI%2FSimpleSSAI/lists"}