ololo
ololo

Reputation: 2034

CLIENT_ERROR when uploading Video To LinkedIn API

I followed the LinkedIn docs Here to upload a Video to their Vector Assets API

The video uploaded, but When I checked the status of the Video I keep getting CLIENT_ERROR under recipes.

This is the code I used:

let fileName = 'redacted.mp4'; //This sample file is about 24MB
let fileStream = fs.createReadStream(fileName);
let organisationId = 'redacted';
let isVideo = module.exports.isVideo(fileName);
let fileStats = fs.statSync(fileName);
let fileSizeBytes = fileStats.size;

let mediaUploadInitAction = `https://api.linkedin.com/v2/assets?action=registerUpload`;

let registerUploadRequest = {
    "registerUploadRequest": {
        "owner": `urn:li:organization:${organisationId}`,
        "recipes": [
            `urn:li:digitalmediaRecipe:feedshare-${isVideo ? 'video' : 'image'}`
        ],
        "serviceRelationships": [
            {
                "identifier": "urn:li:userGeneratedContent",
                "relationshipType": "OWNER"
            }
        ]
    }
};
if (!isVideo) {
    registerUploadRequest['registerUploadRequest']["supportedUploadMechanism"] = [
        "SYNCHRONOUS_UPLOAD"
    ]
} else {
    if (fileSizeBytes > 52428800) { //I was told if the file length is more than 52428800, I should use multipart upload mechanism. My current file size is less than that though.
        registerUploadRequest['registerUploadRequest']["supportedUploadMechanism"] = [
            "MULTIPART_UPLOAD"
        ];
        registerUploadRequest['registerUploadRequest']['fileSize'] = fileSizeBytes;
    }
}

let { data: mediaUploadRegisterResponse } = await axios.post(mediaUploadInitAction, registerUploadRequest, { headers: headers });
let uploadRegisterData = mediaUploadRegisterResponse.value;
let uploadMechanism = uploadRegisterData['uploadMechanism'];
let singleUploadRequest = uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'];
let uploadUrl = singleUploadRequest ? singleUploadRequest['uploadUrl'] : '';
let uploadHeaders = singleUploadRequest ? singleUploadRequest['headers'] : '';

let multipartUpload = uploadMechanism['com.linkedin.digitalmedia.uploading.MultipartUpload'];
if (singleUploadRequest) { //This always work flawlessly for image uploads but not for video uploads
    await axios.put(uploadUrl, fileStream, {
        headers: {
            'Accept': '*/*',
            ...uploadHeaders,
            ...headers,
            'Content-Type': 'application/octet-stream'
        },
        maxContentLength: Infinity,
        maxBodyLength: Infinity,
    });
    fs.unlink(fileName, () => { });
}

The above code works flawlessly for Image Uploads. But for Video Uploads, I keep getting back CLIENT_ERROR.

This is the full status message I keep getting back:

{
    "recipes": [
        {
            "recipe": "urn:li:digitalmediaRecipe:feedshare-video",
            "status": "CLIENT_ERROR"
        }
    ],
    "serviceRelationships": [
        {
            "relationshipType": "OWNER",
            "identifier": "urn:li:userGeneratedContent"
        }
    ],
    "mediaTypeFamily": "VIDEO",
    "created": 1641646213127,
    "id": "C4adhdhahahhdKJZw",
    "lastModified": 1641646215307,
    "status": "ALLOWED"
}

Please, what can I do to resolve this?

Thank you

Upvotes: 0

Views: 605

Answers (1)

ololo
ololo

Reputation: 2034

For anyone who might experience similar issue in the future. After brute-forcing all possible options, here is what worked for me.

If the video file is less than 52MB don't use fs.createReadStream. Use the code below instead:

 fs.readFile(fileName, async (err, data) => {
    if (err) {
        console.log(`Error Reading LinkedIn Video File ${fileName}`, err);        
        return;                   
    }
    await axios.put(uploadUrl, data, {
        headers: singleFileUploadHeaders,
        maxContentLength: Infinity,
        maxBodyLength: Infinity,
   });
});

And the video finally uploaded without any CLIENT_ERROR again!!!

Upvotes: 1

Related Questions